From ae510ed89aa0a0ceef714ed58a868ae95809c6b6 Mon Sep 17 00:00:00 2001 From: aullik Date: Wed, 5 Oct 2016 18:01:04 +0200 Subject: [PATCH] deactivated updates, changed icon, changed save location. startet Work --- assets/img/chatty - old.png | Bin 0 -> 930 bytes assets/img/chatty.png | Bin 930 -> 1155 bytes src/chatty/Chatty.java | 453 ++++++++++++++++---------------- src/chatty/gui/app_16 - old.png | Bin 0 -> 782 bytes src/chatty/gui/app_16.png | Bin 782 -> 943 bytes src/chatty/gui/app_64 - old.png | Bin 0 -> 3770 bytes src/chatty/gui/app_64.png | Bin 3770 -> 5197 bytes 7 files changed, 227 insertions(+), 226 deletions(-) create mode 100644 assets/img/chatty - old.png create mode 100644 src/chatty/gui/app_16 - old.png create mode 100644 src/chatty/gui/app_64 - old.png diff --git a/assets/img/chatty - old.png b/assets/img/chatty - old.png new file mode 100644 index 0000000000000000000000000000000000000000..0ee1eb86116d352a3159a7a103f786974c7a090b GIT binary patch literal 930 zcmV;T16}-yP)<-TwZ5F-BnwCI@Y`0%nJA3w*zLAju z-)b3}{hFH9hzLpI2_r`scsdlqpzQag57 zGdO5ywG4fInz9ta(4n%IWi^%FT5;6%1c9gX z%rQDT3BcmwMLHcv5I9y=eq(-qoU2#ABS}1IS~1TB*qkUygfMWFg(u52?e-+o)9-Qq z{AupoxrVj9EH7VRWMmIJcfLaudE(fUB%Y%DTS$mwPbVnJb3?r@SgV+u`EG>TU#M;*HBH(=`zJ;=kdb8}&LY_bVmhI^2 zdGX5Z>}`4b@E@{w@8?phwLj)LV7JxAdpD6~ilTVRy?fvMS`-_fJdcq2cQG(9^;)}q z=x1Y^;lqauPqXaNJ|N@&!rH+BV+M{jo8u$fKlv~G1=RENhxWo`>;M1&07*qoM6N<$ Eg5`9$h5!Hn literal 0 HcmV?d00001 diff --git a/assets/img/chatty.png b/assets/img/chatty.png index 0ee1eb86116d352a3159a7a103f786974c7a090b..a1d5fe052bb21ec3e10f89e8653f15f86186dc5b 100644 GIT binary patch delta 1134 zcmV-!1d;oq2ZITaB!2;OQb$4nuFf3k00004XF*Lt006O%3;baP00009a7bBm000XT z000XT0n*)m`~Uy|2XskIMF-vn1{4SmdWF#-0000PbVXQnQ*UN;cVTj60B~VxZgehg zWpp4kE-)@JFs%v-zyJUP;7LS5R5(w4lYdN8R}{xt+{PS2DSx&Il+se94vpL5s0-Z^ zn2AA9$_Ck(F_(hQ_y+`nI-`k@fr<+C2Z}}!F-8%XBw7TP3~5Wn2noz}Ch{v`T7<$w zN~sXx@xpiay>3p)=1acGJ@?-CIp1?mt``7afi{~d{r>$1VznBH*=!^x6R+FEVlk5T z_6E|?afftu-G3oATO)b=xS0$L{6dC?EZbRjO2IRDh>z1bGEInTVbdllr_}~4b_UgMn-xyg+*J~_;^38U+)98+FJl96f(58w^75M&u;HWL4gjLnG)>Y&4WTv zPC>1$#AUbhAV;s}(4j4CLZS%Tza6O~#h96yfx|IO9VA1qkHwQGJpwQ{H}YRc=fhw! z5trb|L4QHT#Yt>(vOnVDe1$Uf`gq}|?U_kfyLKtGS|3`L9EF8R$jXvo|NbBxI~IzI z7ZtErDCk+8$ZK@8S7R_FvuWRpv3auyv9ZfgTAC+-5)&ez{bCt5ZuCRSH)5J#IdXDV zAU{7CCr*Uo@?{0?-6O8yVG3fHUd`FFU$cA@(|^(epiA<{$&*(&4Yl;G4U9XM_dH*fwx6Uk9osif-&ba(4Lpoxh-O?7oDd+=Z|_Us8lc6K0k?UK?9 z4SxcxyZbgeJ8OhB!}QUT#!C2|xMg@6b0&D^&y z2vt?v=-9h3Hr4~HwFG5lN>ortb+rmc<4QWQRe1C$(*t_(VlcX;W!pTT<;)p53)2RZ z)69(B!8ft4PKBSTCMF&-bibKl+M1s~Z)bLe@-Kd=9lUcP*0xo3Mf z3ct3fsqG)Zvd)6Vcm7L@H<-TwZ5F-BnwCI@Y`0%nJA3w*zLAju-)b3}{hFH9hzLpI2_r`scsdi506R%__qo<47MWyu&ty{-s?#~eL6%kJGh%*-@7etd>ow|+uv(7Lj% z0j;%C3N!*OH1$N0 zV|_g&O@AAtsgPx!Jol7kHI?34an$t$fv5A#F*-U4z~bUXIvqz4I967EV}5>|t5?4x zNjzy zEPpM2@Wk5I?;_xRCBB8SjC!-|(L$a-{+8|N>3Q+W?CfoM`|uyKckky?tF=GoIbgTd z#(OuBWs0JB%DsEv{8|(npFEF{`gbufF!fryeduRnn&HET3s1A`(LNyK|H9hA0b>S^ iHJjrj+dug)`~}qW^N04rWb6O{002ovP6b4+LSTaU;JDQQ diff --git a/src/chatty/Chatty.java b/src/chatty/Chatty.java index e2e3fbc3b..7705a27ba 100644 --- a/src/chatty/Chatty.java +++ b/src/chatty/Chatty.java @@ -5,241 +5,242 @@ import chatty.util.LogUtil; import chatty.util.MiscUtil; import chatty.util.SingleInstance; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + import java.io.File; import java.util.HashMap; import java.util.Map; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; /** * Main class that starts the client as well as parses the commandline * parameters and provides some app-specific global constants. - * + * * @author tduva */ public class Chatty { - - /** - * Enables debug commands as well as some other behaviour that allows - * debugging. Should be disabled for a regular release. - */ - public static final boolean DEBUG = false; - - /** - * Enables the hotkey feature for running commercials (windows only). - */ - public static final boolean HOTKEY = MiscUtil.OS_WINDOWS; - - /** - * The Chatty website as it can be opened in the menu. - */ - public static final String WEBSITE = - "http://chatty.github.io"; - - /** - * The Twitch client id of this program. - * - * If you compile this program yourself, you should create your own client - * id on http://www.twitch.tv/kraken/oauth2/clients/new - */ - public static final String CLIENT_ID = "spyiu9jqdnfjtwv6l1xjk5zgt8qb91l"; - - /** - * The redirect URI for getting a token. - */ - public static final String REDIRECT_URI = "http://127.0.0.1:61324/token/"; - - /** - * Version number of this version of Chatty, consisting of numbers seperated - * by points. May contain a single "b" for beta versions, anything following - * it will be ignored for version checking. - */ - public static final String VERSION = "0.8.4b6"; - - /** - * Enable Version Checker (if you compile and distribute this yourself, you - * may want to disable this) - */ - public static final boolean VERSION_CHECK_ENABLED = true; - - /** - * The regular URL of the textfile where the most recent version is stored. - */ - public static final String VERSION_URL = "http://chatty.github.io/version.txt"; - - /** - * For testing purposes. - */ - public static final String VERSION_TEST_URL = "http://127.0.0.1/twitch/version.txt"; - - public static final String COMPILE_INFO = "JDK8"; - - /** - * For use with the -single commandline argument, if no port is specified. - * Unregistered port from the User Ports range. - */ - private static final int DEFAULT_SINGLE_INSTANCE_PORT = 48724; - - // End of configuration - - /** - * When this program was started - */ - public static final long STARTED_TIME = System.currentTimeMillis(); - - /** - * If true, use the current working directory to save settings etc. - */ - private static boolean useCurrentDirectory = false; - - /** - * Parse the commandline arguments and start the actual chat client. - * - * @param args The commandline arguments. - */ - public static void main(String[] args) { - Map parsedArgs = MiscUtil.parseArgs(args); - - /** - * Continue only if single instance mode isn't enabled or registering - * succeeded. - */ - if (parsedArgs.containsKey("single")) { - int port = getInstancePort(parsedArgs); - if (!SingleInstance.registerInstance(port)) { - SingleInstance.notifyRunningInstance(port, - encodeParametersToJSON(parsedArgs)); - // Exit program - return; - } - } - - if (parsedArgs.containsKey("cd")) { - useCurrentDirectory = true; - } - - final TwitchClient client = new TwitchClient(parsedArgs); - - // Adding listener just in case, will do nothing if not used - SingleInstance.setNewInstanceListener(new SingleInstance.NewInstanceListener() { - - @Override - public void newInstance(String message) { - Map args = decodeParametersFromJSON(message); - if (args.containsKey("channel")) { - String channel = args.get("channel"); - client.joinChannels(Helper.parseChannelsFromString(channel, false)); - } - } - }); - - LogUtil.startMemoryUsageLogging(); - } - - /** - * Encodes the given Map of parameters to a JSON String. - * - * @param parameters The Map of parsed parameters - * @return The JSON String - */ - private static String encodeParametersToJSON(Map parameters) { - JSONObject object = new JSONObject(); - object.putAll(parameters); - return object.toJSONString(); - } - - /** - * Decodes the given JSON String into a Map of parameters. - * - * @param json The JSON String - * @return The Map of parameters or an empty Map if any error occurs - */ - private static Map decodeParametersFromJSON(String json) { - try { - JSONParser parser = new JSONParser(); - JSONObject root = (JSONObject)parser.parse(json); - Map result = new HashMap<>(); - for (Object key : root.keySet()) { - result.put((String)key, (String)root.get(key)); - } - return result; - } catch (Exception ex) { - return new HashMap(); - } - } - - private static int getInstancePort(Map args) { - int port = DEFAULT_SINGLE_INSTANCE_PORT; - String arg = args.get("single"); - if (arg != null) { - try { - port = Integer.parseInt(arg); - } catch (NumberFormatException ex) { - // Use default + + /** + * Enables debug commands as well as some other behaviour that allows + * debugging. Should be disabled for a regular release. + */ + public static final boolean DEBUG = true; + + /** + * Enables the hotkey feature for running commercials (windows only). + */ + public static final boolean HOTKEY = MiscUtil.OS_WINDOWS; + + /** + * The Chatty website as it can be opened in the menu. + */ + public static final String WEBSITE = + "http://chatty.github.io"; + + /** + * The Twitch client id of this program. + *

+ * If you compile this program yourself, you should create your own client + * id on http://www.twitch.tv/kraken/oauth2/clients/new + */ + public static final String CLIENT_ID = "spyiu9jqdnfjtwv6l1xjk5zgt8qb91l"; + + /** + * The redirect URI for getting a token. + */ + public static final String REDIRECT_URI = "http://127.0.0.1:61324/token/"; + + /** + * Version number of this version of Chatty, consisting of numbers seperated + * by points. May contain a single "b" for beta versions, anything following + * it will be ignored for version checking. + */ + public static final String VERSION = "0.8.4b6"; + + /** + * Enable Version Checker (if you compile and distribute this yourself, you + * may want to disable this) + */ + public static final boolean VERSION_CHECK_ENABLED = false; + + /** + * The regular URL of the textfile where the most recent version is stored. + */ + public static final String VERSION_URL = "http://chatty.github.io/version.txt"; + + /** + * For testing purposes. + */ + public static final String VERSION_TEST_URL = "http://127.0.0.1/twitch/version.txt"; + + public static final String COMPILE_INFO = "JDK8"; + + /** + * For use with the -single commandline argument, if no port is specified. + * Unregistered port from the User Ports range. + */ + private static final int DEFAULT_SINGLE_INSTANCE_PORT = 48724; + + // End of configuration + + /** + * When this program was started + */ + public static final long STARTED_TIME = System.currentTimeMillis(); + + /** + * If true, use the current working directory to save settings etc. + */ + private static boolean useCurrentDirectory = false; + + /** + * Parse the commandline arguments and start the actual chat client. + * + * @param args The commandline arguments. + */ + public static void main(String[] args) { + Map parsedArgs = MiscUtil.parseArgs(args); + + /** + * Continue only if single instance mode isn't enabled or registering + * succeeded. + */ + if (parsedArgs.containsKey("single")) { + int port = getInstancePort(parsedArgs); + if (!SingleInstance.registerInstance(port)) { + SingleInstance.notifyRunningInstance(port, + encodeParametersToJSON(parsedArgs)); + // Exit program + return; + } + } + + if (parsedArgs.containsKey("cd")) { + useCurrentDirectory = true; + } + + final TwitchClient client = new TwitchClient(parsedArgs); + + // Adding listener just in case, will do nothing if not used + SingleInstance.setNewInstanceListener(new SingleInstance.NewInstanceListener() { + + @Override + public void newInstance(String message) { + Map args = decodeParametersFromJSON(message); + if (args.containsKey("channel")) { + String channel = args.get("channel"); + client.joinChannels(Helper.parseChannelsFromString(channel, false)); } - } - return port; - } - - /** - * Gets the directory to save data in (settings, cache) and also creates it - * if necessary. - * - * @return - */ - public static String getUserDataDirectory() { - if (useCurrentDirectory) { - return System.getProperty("user.dir") + File.separator; - } - String dir = System.getProperty("user.home") - + File.separator - + ".chatty" - + File.separator; - new File(dir).mkdirs(); - return dir; - } - - public static String getExportDirectory() { - String dir = getUserDataDirectory()+"exported"+File.separator; - new File(dir).mkdirs(); - return dir; - } - - public static String getCacheDirectory() { - String dir = getUserDataDirectory()+"cache"+File.separator; - new File(dir).mkdirs(); - return dir; - } - - public static String getWorkingDirectory() { - return System.getProperty("user.dir")+File.separator; - } - - public static String getSoundDirectory() { - return getWorkingDirectory()+"sounds"+File.separator; - } - - public static String getImageDirectory() { - return getWorkingDirectory()+"img"+File.separator; - } - - public static String getBackupDirectory() { - return getUserDataDirectory()+"backup"+File.separator; - } - - public static String getDebugLogDirectory() { - return getUserDataDirectory()+"debuglogs"+File.separator; - } - - public static String chattyVersion() { - return String.format("Chatty Version %s%s%s / %s", - Chatty.VERSION, - (Chatty.HOTKEY ? " Hotkey": ""), - (Chatty.DEBUG ? " (Debug)" : ""), - COMPILE_INFO); - } - - public static String uptime() { - return DateTime.ago(STARTED_TIME); - } + } + }); + + LogUtil.startMemoryUsageLogging(); + } + + /** + * Encodes the given Map of parameters to a JSON String. + * + * @param parameters The Map of parsed parameters + * @return The JSON String + */ + private static String encodeParametersToJSON(Map parameters) { + JSONObject object = new JSONObject(); + object.putAll(parameters); + return object.toJSONString(); + } + + /** + * Decodes the given JSON String into a Map of parameters. + * + * @param json The JSON String + * @return The Map of parameters or an empty Map if any error occurs + */ + private static Map decodeParametersFromJSON(String json) { + try { + JSONParser parser = new JSONParser(); + JSONObject root = (JSONObject) parser.parse(json); + Map result = new HashMap<>(); + for (Object key : root.keySet()) { + result.put((String) key, (String) root.get(key)); + } + return result; + } catch (Exception ex) { + return new HashMap(); + } + } + + private static int getInstancePort(Map args) { + int port = DEFAULT_SINGLE_INSTANCE_PORT; + String arg = args.get("single"); + if (arg != null) { + try { + port = Integer.parseInt(arg); + } catch (NumberFormatException ex) { + // Use default + } + } + return port; + } + + /** + * Gets the directory to save data in (settings, cache) and also creates it + * if necessary. + * + * @return + */ + public static String getUserDataDirectory() { + if (useCurrentDirectory) { + return System.getProperty("user.dir") + File.separator; + } + String dir = System.getProperty("user.home") + + File.separator + + ".chatty2" + + File.separator; + new File(dir).mkdirs(); + return dir; + } + + public static String getExportDirectory() { + String dir = getUserDataDirectory() + "exported" + File.separator; + new File(dir).mkdirs(); + return dir; + } + + public static String getCacheDirectory() { + String dir = getUserDataDirectory() + "cache" + File.separator; + new File(dir).mkdirs(); + return dir; + } + + public static String getWorkingDirectory() { + return System.getProperty("user.dir") + File.separator; + } + + public static String getSoundDirectory() { + return getWorkingDirectory() + "sounds" + File.separator; + } + + public static String getImageDirectory() { + return getWorkingDirectory() + "img" + File.separator; + } + + public static String getBackupDirectory() { + return getUserDataDirectory() + "backup" + File.separator; + } + + public static String getDebugLogDirectory() { + return getUserDataDirectory() + "debuglogs" + File.separator; + } + + public static String chattyVersion() { + return String.format("Chatty Version %s%s%s / %s", + Chatty.VERSION, + (Chatty.HOTKEY ? " Hotkey" : ""), + (Chatty.DEBUG ? " (Debug)" : ""), + COMPILE_INFO); + } + + public static String uptime() { + return DateTime.ago(STARTED_TIME); + } } diff --git a/src/chatty/gui/app_16 - old.png b/src/chatty/gui/app_16 - old.png new file mode 100644 index 0000000000000000000000000000000000000000..32700a46d909759e607a063d2a2660cd3f0f209c GIT binary patch literal 782 zcmV+p1M&QcP)=^UXJN?@gODKhjvGL_`{DwL+y45pmI? z#*IkTlAYZO;!aVJB7)k5q9PWR-c3Ph7g|J$ixNt}x(czNR0N~xkH+46Gs&GhGntw1 z$Hnz3f&pJRi*q>V<#68f3Lt<7CV|@l^H=S^;DG?x0G8=D3gBnTtx$w!Y)Hbz3D zLd05+Si$Cy#1&=FQ>M;WiISyXFZ!j`ub;Qpo)UnOZDY-|?=BpB_>p@|IOcRXu0TU~ z1==gH-9vmGT2~#}P48A$*3|3svp+0vEFRDRqr(&Www+VlT+3-F{P=K<9;4H=ZN@y=1+; zi8q3+z`OpP`veX)yN*yhx{)F2R*2EGRy^?^CAKI1BW8{&ci7zHod-Y-2(sAHYa6nb z=fGXNx$x~3uKnC2NJC!u@GK|4S|F?<^2AZ54rlq-1}njDQ0HAc)bYw>kP3pZ;WR=RgmMk`m>merewjhm-irbmWlS+9DS9%xJ zH|xzyh0RV2fQUpI(2?WI9Xa}1n>g7=h~gZ zrEhxYZw!81lmr35uKM27AJ1g|<$d!$QbQ;D|1N3^Z~Tow^#!^A?vcaki_>5FTN``M z1Cb&SL1{q+|AYhs1qT=;v$bIRCxL`d05$2Gaw}(U4H1QilK(UOC#%a&-{^1QsQ>@~ M07*qoM6N<$g4#K7y8r+H literal 0 HcmV?d00001 diff --git a/src/chatty/gui/app_16.png b/src/chatty/gui/app_16.png index 32700a46d909759e607a063d2a2660cd3f0f209c..4e6ed719d61a4698d9ad83cd8d5608e00f86755c 100644 GIT binary patch delta 921 zcmV;K17`e=2CoN@B!2;OQb$4nuFf3k00004XF*Lt006O%3;baP00009a7bBm000XS z000XS0e@s)kpKVy8FWQhbW?9;ba!ELWdLwtX>N2bZe?^JG%heMF)*zP3cvsW10P95 zK~y+TeUo`mjA0zd-|e*9W!u?gOF1Won24E-ag4jeeMN0UDSv5f*pv{45yp@iHA7=e zTFFt7dy0QBNIFo-#3r4#q@~*SJ)W=U-4SLSe|+BO_dd__{rsMJW*!EBgd&cEC=)5; zDHHyIxaLP0P7yN<{SdL3^78HTmIJ4>Lh>PvIcdL!-E}aYO-|LYd(t%Q(JU>SmY2Y0 z+)XrRK2Bgun}2SZd7h8_Apm3S?mRa?dK_dv3}@?R1;&P#}{9IALgjlp8ckN^GT8B=ztd()MWwF?1x7vYKeJ zBE_4`-RDX|&v@{wugFl+mRCcw11y3@gFf3oRDqE*2Y+xfF9w>V$>{Cfi@-2%OkJf! zT|*pl9t6=7IAG1$!9r-hBVHH^-~1Fbwd-{OkqV4mB;yo*5A?$`D$~vz95;T9->t=0J!au^18@9j})$d|)zAy-$^CSp}a>2B% z&RBTR6@SYzlu%z*3G0iUP~Q3530l7BbwLN*F;hE`8yjv1-MwHm8xjx@>x3!sGE}^a z!i|b02+4Fo%pFf5=7|d`jlT(6jr#K|(^Uveb>-)#$Pu_tiB}(@(Dr3J8Vy^~WlBWi z%`phicSHOmZ(&QN92H&H#Y?oe2-x*pTOe^#v+~T~!hF zH4kjQ?*(ni2<&`45=qrV`ONyYF!mV=#jHg@2(jzqdiQj*ow-j97vFC$^}?nSXHwLf z)_>i{f4%a_RCl4nT%SX^&~C23Wa7SM5P^976i_4r;jP8G#Z;q*N!7;Uo|Cm9XzhJ_hyL3M;3Wit4aNEwL~Le}_6zzuEbQaIW%7g# vq_sWWD9-i2*1z)CNkRk>G5Fsw0OmV}coL#w@~!g+fLZuNAanYj2jY!p!o!tuJPEn8|g4%_mA{Le2O+jcET11MA z5=y|j3bCM61f%JX#@>4~$(=hhnVIj$#q}zJ0be+ab2#VaaDU$O3Lt<7CV|@l^H=S^ z;DG?x0G8=D3gBnTtx$w!Y)Hbz3DLd05+Si$Cy#1&=FQ>M;WiISyXFZ!j`ub;Qp zo)UnOZDY-|?=BpB_>p@|IOcRXu0TU~1==gH-9vmGT2~#}P48A$*3|3svp+0vEFRDR zqr(&Www+VlTz|`HDE#MjA?a3#(X>`P z@gF6&C;cO4jw*N9+~b`GKn)18*wSkovX*5+#^UsUik1VC%;-CtRnKn zQKk-O`PT+6TXTqU@>`ZN_uvCu{&AJ3Uj39XR3u5s+~J2b+8A zmCCx7EH;emAtv;;AdQWR+nLIfN_h)cdKc6;>&;7r%}xt|h(u9Pe@RPy-@T)c&pb2r z_MJm&)PH{Uc(%|wb$&-USz2cV@B+H$+MU9sZ*O|%Zw!81lmr35uKM27AJ1g|<$d!$ zQbQ;D|1N3^Z~Tow^#!^A?vcaki_>5FTN``M1Cb&SL1{q+|AYhs1qT=;v$bIRCxL`d o05$2Gaw}(U4H1QilK(UOC#%a&-{^1QsQ>@~07*qoM6N<$g7t=QCIA2c diff --git a/src/chatty/gui/app_64 - old.png b/src/chatty/gui/app_64 - old.png new file mode 100644 index 0000000000000000000000000000000000000000..91b8bb43740d56ebb3d4ae190687681801d0bd38 GIT binary patch literal 3770 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 literal 0 HcmV?d00001 diff --git a/src/chatty/gui/app_64.png b/src/chatty/gui/app_64.png index 91b8bb43740d56ebb3d4ae190687681801d0bd38..e01046616e87a607b76968749c1bbf2c05efa86d 100644 GIT binary patch literal 5197 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