diff --git a/locCommands.config b/locCommands.config new file mode 100644 index 0000000..4266161 --- /dev/null +++ b/locCommands.config @@ -0,0 +1,38 @@ +[ObjectBuilderFactory] +indicator= +boop=bap, spaghetti, turboyeet +tony, stark, dontfeelgood, dontfeelsogood= +yeet= +role= +ping= +rating= +roll= +blur= +choose= +poll= +rpstart= +bet= +perish, thenperish= +teey= +stats= +beans= +eightball, 8ball= +vote= +results= +wolfram= +map= +info, about= +givebeans= +c++, g++, cplus, cpp= +work= +showpoll= +rpend= +rpg= +tweet= +java, jdoodle= +help= +buildHelp= +invite= +shutdown= + + diff --git a/src/core/CommandManager.java b/src/core/CommandManager.java index e3e8970..53a5f5a 100644 --- a/src/core/CommandManager.java +++ b/src/core/CommandManager.java @@ -29,9 +29,16 @@ public class CommandManager // Allows the command manager to keep track of a command. public void Register(String key, Command command) - { + { if(key == null) - return; + return; + + if(key.contains(",")) + { + String[] keys = key.split(","); + Register(keys, command); + return; + } key = key.toLowerCase(); command.registeredNames.add(key); @@ -51,7 +58,7 @@ public class CommandManager public void Register(String[] keys, Command command) { for(int i = 0; i < keys.length; ++i) - Register(keys[i], command); + Register(keys[i].trim(), command); } // Calls the command but on a whole new thread! diff --git a/src/core/LocBase.java b/src/core/LocBase.java new file mode 100644 index 0000000..6fdcd49 --- /dev/null +++ b/src/core/LocBase.java @@ -0,0 +1,190 @@ +package core; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import dataStructures.SectionedKeyValueStore; +import utils.FileUtils; +import utils.GlobalLog; +import utils.LogFilter; + +// A quick-and-dirty localization tool that scrapes the project for calls to itself, then +// generates/updates a file externally with all the stub values as keys that are localized. +public abstract class LocBase +{ + // Pre-defined values + public static final String KittySourceDirectory = "./src"; + + // Filename + public final String filename; // Example: "localization.config"; + public final String functionName; // Example: "Localizer.Stub"; + + // Local translation storage + private SectionedKeyValueStore stringStore; + + // Logging + private void Log(String str) { GlobalLog.Log(LogFilter.Strings, str); } + private void Warn(String str) { GlobalLog.Warn(LogFilter.Strings, str); } + private void Error(String str) { GlobalLog.Error(LogFilter.Strings, str); } + + // Ok... so this is an array because if it's not an array, the parser will parse the string + public LocBase(String filename, String functionName) + { + this.filename = filename; + this.functionName = functionName; + } + + // Structure used for holding a pair of strings and any other info we need + // about localized information that is being looked up. + private class LocInfo + { + public String file; + public String phrase; + + public LocInfo(String f, String p) + { + this.file = f; + this.phrase = p; + } + } + + // Do processing on each path in the scraped directory here, assuming it's .java + public void StripForContents(Path path, ArrayList strings) + { + String filename = path.getFileName().toString(); + if(filename.contains(".java")) + { + String contents = FileUtils.ReadContent(path); + String[] split = contents.split(functionName); + + // Identify all localizer function calls + for(int i = 1; i < split.length; ++i) + { + int loc = split[i].indexOf(")"); + String noWhitespace = split[i].replaceAll("\\s+",""); + + if(loc != -1) + { + if(noWhitespace.charAt(noWhitespace.indexOf(")") - 1) == '"' && split[i].charAt(loc - 2) != '\\') + { + // At this point, we find the first ), then verify there's a ") behind it, and that + // the " is not an escaped character. + try + { + String toLocalize = split[i].substring(2, loc - 1); + + strings.add(new LocInfo(filename.substring(0, filename.lastIndexOf('.')), toLocalize)); + + Log("Found lookup call in " + path + ": " + toLocalize); + } + catch(IndexOutOfBoundsException e) + { + Warn("Found phrase but couldn't parse in file " + path); + } + } + } + } + } + } + + // Nothing for now, but in the future will return a parsed and localized version of + // the string in question if one can be found. If the localized string is empty, + // returns a the key instead which is the default phrase. + public String GetKey(String input) + { + if(stringStore == null) + return input; + + String value = stringStore.GetKey(input); + if(value == null || value.trim().length() < 1) + return input; + + return value; + } + + // Reads a file to string, adapted from https://stackoverflow.com/a/326440/5383198 + private String ReadFileAsString(String path, Charset encoding) + { + try + { + byte[] encoded = Files.readAllBytes(Paths.get(path)); + return new String(encoded, encoding); + } + catch (IOException e) + { + Warn("No file found to read from!"); + } + + return null; + } + + // Update localization from the disk on file. Creates the file if it doesn't exist. + // This file is internally formatted as an ini file. + public void UpdateLocFromDisk() + { + Log("Attempting to read localization file: " + filename); + + try + { + String fileContents = ReadFileAsString(filename, Charset.defaultCharset()); + + if(fileContents == null) + { + File file = new File(filename); + file.createNewFile(); + } + + stringStore = new SectionedKeyValueStore(fileContents); + } + catch(IOException e) + { + Error("IO exception during localization file read"); + } + } + + // Rewrites out at the specified filename with existing stubs. + // This preserves existing localized phrases. + public void SaveLocToDisk() + { + Log("Attempting to write updated localization file"); + + try + { + PrintWriter pw = new PrintWriter(filename); + pw.println(stringStore.toString()); + pw.close(); + } + catch(IOException e) + { + Error("IO exception during localization file write"); + } + } + + private void TryStripSpecified(Path path, ArrayList toFill) + { + try + { + StripForContents(path, toFill); + } + catch(Exception e) + { + Error("issue with file: " + path.toString()); + } + } + + // Scrape the project and generate all the possible localizeable phrases. + // This stubs out phrases to be localized. + public void ScrapeAll() + { + ArrayList localizeList = new ArrayList(); + FileUtils.AcquireAllFiles(KittySourceDirectory).forEach((path) -> TryStripSpecified(path, localizeList)); + + for(LocInfo toStub : localizeList) + stringStore.AddKeyValue(toStub.file, toStub.phrase, toStub.phrase); + } +} diff --git a/src/core/LocCommands.java b/src/core/LocCommands.java new file mode 100644 index 0000000..d01ff7b --- /dev/null +++ b/src/core/LocCommands.java @@ -0,0 +1,37 @@ +package core; + +import utils.GlobalLog; +import utils.LogFilter; + +public class LocCommands extends LocBase +{ + public static final String fileName = "locCommands.config"; + public static final String function = "LocCommands.Stub"; + + private static LocCommands instance; + + public LocCommands() + { + super(fileName, function); + + GlobalLog.Log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName()); + + if(instance == null) + { + instance = this; + + UpdateLocFromDisk(); + ScrapeAll(); + SaveLocToDisk(); + } + else + { + GlobalLog.Error(LogFilter.Core, "You can't have two of the following: " + this.getClass().getSimpleName()); + } + } + + public static String Stub(String toStub) + { + return instance.GetKey(toStub); + } +} diff --git a/src/core/Localizer.java b/src/core/Localizer.java index 9487b2e..ba8e536 100644 --- a/src/core/Localizer.java +++ b/src/core/Localizer.java @@ -1,170 +1,40 @@ package core; -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import dataStructures.SectionedKeyValueStore; -import utils.FileUtils; import utils.GlobalLog; import utils.LogFilter; // A quick-and-dirty localization tool that scrapes the project for calls to itself, then // generates/updates a file externally (phrases.config) with all the stub values as keys that // can then be localized. -public class Localizer +public class Localizer extends LocBase { - // Filename - public final static String filename = "localization.config"; - public final static String functionName = "Localizer.Stub"; + public static final String fileName = "localization.config"; + public static final String function = "Localizer.Stub"; - // Local translation storage - private static SectionedKeyValueStore stringStore; + private static Localizer instance; - // Logging - private static void Log(String str) { GlobalLog.Log(LogFilter.Strings, str); } - private static void Warn(String str) { GlobalLog.Warn(LogFilter.Strings, str); } - private static void Error(String str) { GlobalLog.Error(LogFilter.Strings, str); } - - - // Structure used for holding a pair of strings and any other info we need - // about localized information that is being looked up. - private static class LocInfo + public Localizer() { - public String file; - public String phrase; + super(fileName, function); - public LocInfo(String f, String p) + GlobalLog.Log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName()); + + if(instance == null) { - this.file = f; - this.phrase = p; - } - } - - // Do processing on each path in the scraped directory here, assuming it's .java - public static void StripForContents(Path path, ArrayList strings) - { - String filename = path.getFileName().toString(); - if(filename.contains(".java")) - { - String contents = FileUtils.ReadContent(path); - String[] split = contents.split(functionName); + instance = this; - // Identify all localizer function calls - for(int i = 1; i < split.length; ++i) - { - int loc = split[i].indexOf(")"); - - if(loc != -1) - { - if(split[i].charAt(loc - 1) == '"' && split[i].charAt(loc - 2) != '\\') - { - // At this point, we find the first ), then verify there's a ") behind it, and that - // the " is not an escaped character. - try - { - String toLocalize = split[i].substring(2, loc - 1); - - strings.add(new LocInfo(filename.substring(0, filename.lastIndexOf('.')), toLocalize)); - - Log("Found stubbed phrase in " + path + " : " + toLocalize); - } - catch(IndexOutOfBoundsException e) - { - Warn("Found phrase but couldn't parse in file " + path); - } - } - } - } + UpdateLocFromDisk(); + ScrapeAll(); + SaveLocToDisk(); } - } - - // Nothing for now, but in the future will return a parsed and localized version of - // the string in question if one can be found. If the localized string is empty, - // returns a the key instead which is the default phrase. - public static String Stub(String input) - { - if(stringStore == null) - return input; - - String value = stringStore.GetKey(input); - if(value == null || value.trim().length() < 1) - return input; - - return value; - } - - // Reads a file to string, adapted from https://stackoverflow.com/a/326440/5383198 - static String ReadFileAsString(String path, Charset encoding) - { - try + else { - byte[] encoded = Files.readAllBytes(Paths.get(path)); - return new String(encoded, encoding); - } - catch (IOException e) - { - Warn("No file found to read from!"); - } - - return null; - } - - // Update localization from the disk on file. Creates the file if it doesn't exist. - // This file is internally formatted as an ini file. - public static void UpdateLocFromDisk() - { - Log("Attempting to read localization file"); - - try - { - String fileContents = ReadFileAsString(filename, Charset.defaultCharset()); - System.out.println("File contents: " + fileContents); - - if(fileContents == null) - { - File file = new File(filename); - file.createNewFile(); - } - - stringStore = new SectionedKeyValueStore(fileContents); - } - catch(IOException e) - { - Error("IO exception during localization file read"); - } - } - - // Rewrites out at the specified filename with existing stubs. - // This preserves existing localized phrases. - public static void SaveLocToDisk() - { - Log("Attempting to write updated localization file"); - - try - { - PrintWriter pw = new PrintWriter(filename); - pw.println(stringStore.toString()); - pw.close(); - } - catch(IOException e) - { - Error("IO exception during localization file write"); + GlobalLog.Error(LogFilter.Core, "You can't have two of the following: " + this.getClass().getSimpleName()); } } - // Scrape the project and generate all the possible localizeable phrases. - // This stubs out phrases to be localized. - public static void ScrapeAll() + public static String Stub(String toStub) { - ArrayList localizeList = new ArrayList(); - FileUtils.AcquireAllFiles(".\\src").forEach((path) -> StripForContents(path, localizeList)); - - for(LocInfo toStub : localizeList) - stringStore.AddKeyValue(toStub.file, toStub.phrase, toStub.phrase); + return instance.GetKey(toStub); } } \ No newline at end of file diff --git a/src/core/ObjectBuilderFactory.java b/src/core/ObjectBuilderFactory.java index e568f71..89c285c 100644 --- a/src/core/ObjectBuilderFactory.java +++ b/src/core/ObjectBuilderFactory.java @@ -286,44 +286,44 @@ public class ObjectBuilderFactory CommandManager manager = new CommandManager(); - manager.Register("work", new CommandDoWork(KittyRole.Dev, KittyRating.Safe)); - manager.Register("shutdown", new CommandShutdown(KittyRole.Dev, KittyRating.Safe)); - manager.Register("stats", new CommandStats(KittyRole.Dev, KittyRating.Safe)); - manager.Register("invite", new CommandInvite(KittyRole.Dev, KittyRating.Safe)); - manager.Register("buildHelp", new CommandHelpBuilder(KittyRole.Dev, KittyRating.Safe)); - manager.Register("tweet", new CommandTweet(KittyRole.Dev, KittyRating.Safe)); + manager.Register(LocCommands.Stub("work"), new CommandDoWork(KittyRole.Dev, KittyRating.Safe)); + manager.Register(LocCommands.Stub("shutdown"), new CommandShutdown(KittyRole.Dev, KittyRating.Safe)); + manager.Register(LocCommands.Stub("stats"), new CommandStats(KittyRole.Dev, KittyRating.Safe)); + manager.Register(LocCommands.Stub("invite"), new CommandInvite(KittyRole.Dev, KittyRating.Safe)); + manager.Register(LocCommands.Stub("buildHelp"), new CommandHelpBuilder(KittyRole.Dev, KittyRating.Safe)); + manager.Register(LocCommands.Stub("tweet"), new CommandTweet(KittyRole.Dev, KittyRating.Safe)); - manager.Register("rating", new CommandRating(KittyRole.Admin, KittyRating.Safe)); - manager.Register("indicator", new CommandChangeIndicator(KittyRole.Admin, KittyRating.Safe)); + manager.Register(LocCommands.Stub("rating"), new CommandRating(KittyRole.Admin, KittyRating.Safe)); + manager.Register(LocCommands.Stub("indicator"), new CommandChangeIndicator(KittyRole.Admin, KittyRating.Safe)); - manager.Register("poll", new CommandPollManage(KittyRole.Mod, KittyRating.Safe)); - manager.Register("givebeans", new CommandGiveBeans(KittyRole.Mod, KittyRating.Safe)); - manager.Register("rpg", new CommandRPG(KittyRole.Mod, KittyRating.Safe)); + manager.Register(LocCommands.Stub("poll"), new CommandPollManage(KittyRole.Mod, KittyRating.Safe)); + manager.Register(LocCommands.Stub("givebeans"), new CommandGiveBeans(KittyRole.Mod, KittyRating.Safe)); + manager.Register(LocCommands.Stub("rpg"), new CommandRPG(KittyRole.Mod, KittyRating.Safe)); - manager.Register("teey", new CommandTeey(KittyRole.General, KittyRating.Safe)); - manager.Register(new String[]{"perish", "thenperish"}, new CommandPerish(KittyRole.General, KittyRating.Safe)); - manager.Register("yeet", new CommandYeet(KittyRole.General, KittyRating.Safe)); - manager.Register("ping", new CommandPing(KittyRole.General, KittyRating.Safe)); - manager.Register("boop", new CommandBoop(KittyRole.General, KittyRating.Safe)); - manager.Register("roll", new CommandRoll(KittyRole.General, KittyRating.Safe)); - manager.Register("choose", new CommandChoose(KittyRole.General, KittyRating.Safe)); - manager.Register("help", new CommandHelp(KittyRole.General, KittyRating.Safe)); - manager.Register(new String[] {"info", "about"}, new CommandInfo(KittyRole.General, KittyRating.Safe)); - manager.Register("vote", new CommandPollVote(KittyRole.General, KittyRating.Safe)); - manager.Register("results", new CommandPollResults(KittyRole.General, KittyRating.Safe)); - manager.Register("showpoll", new CommandPollShow(KittyRole.General, KittyRating.Safe)); - manager.Register("wolfram", new CommandWolfram(KittyRole.General, KittyRating.Safe)); - manager.Register(new String[] {"c++", "g++", "cplus","cpp"}, new CommandColiru(KittyRole.General, KittyRating.Safe)); - manager.Register(new String[] {"java", "jdoodle" }, new CommandJDoodle(KittyRole.General, KittyRating.Safe)); - manager.Register("beans", new CommandBeansShow(KittyRole.General, KittyRating.Safe)); - manager.Register("role", new CommandRole(KittyRole.General, KittyRating.Safe)); - manager.Register("bet", new CommandBetBeans(KittyRole.General, KittyRating.Safe)); - manager.Register("map", new CommandMap(KittyRole.General, KittyRating.Safe)); - manager.Register("rpstart", new CommandRPStart(KittyRole.General, KittyRating.Safe)); - manager.Register("rpend", new CommandRPEnd(KittyRole.General, KittyRating.Safe)); - manager.Register(new String[] {"tony", "stark", "dontfeelgood", "dontfeelsogood"}, new CommandStark(KittyRole.General, KittyRating.Safe)); - manager.Register("blur", new CommandBlurry(KittyRole.General, KittyRating.Safe)); - manager.Register(new String [] {"eightball", "8ball"}, new CommandEightBall(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("teey"), new CommandTeey(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("perish, thenperish"), new CommandPerish(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("yeet"), new CommandYeet(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("ping"), new CommandPing(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("boop"), new CommandBoop(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("roll"), new CommandRoll(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("choose"), new CommandChoose(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("help"), new CommandHelp(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("info, about"), new CommandInfo(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("vote"), new CommandPollVote(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("results"), new CommandPollResults(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("showpoll"), new CommandPollShow(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("wolfram"), new CommandWolfram(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("c++, g++, cplus, cpp"), new CommandColiru(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("java, jdoodle"), new CommandJDoodle(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("beans"), new CommandBeansShow(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("role"), new CommandRole(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("bet"), new CommandBetBeans(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("map"), new CommandMap(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("rpstart"), new CommandRPStart(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("rpend"), new CommandRPEnd(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("tony, stark, dontfeelgood, dontfeelsogood"), new CommandStark(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("blur"), new CommandBlurry(KittyRole.General, KittyRating.Safe)); + manager.Register(LocCommands.Stub("eightball, 8ball"), new CommandEightBall(KittyRole.General, KittyRating.Safe)); return manager; } diff --git a/src/main/Main.java b/src/main/Main.java index ff780a7..653667c 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -29,14 +29,16 @@ public class Main extends ListenerAdapter private static DatabaseManager databaseManager; private static Stats stats; private static RPManager rpManager; + private static Localizer locStrings; + private static LocCommands locCommands; // Main test location public static void main(String[] args) throws InterruptedException, LoginException, Exception { // Localizer startup - Potentially integrate with the factory. Needs to happen first tho. - Localizer.UpdateLocFromDisk(); - Localizer.ScrapeAll(); - Localizer.SaveLocToDisk(); + locStrings = new Localizer(); + locCommands = new LocCommands(); + // Factory startup databaseManager = ObjectBuilderFactory.ConstructDatabaseManager(); diff --git a/src/utils/FileUtils.java b/src/utils/FileUtils.java index 4d3ef48..ba70d6a 100644 --- a/src/utils/FileUtils.java +++ b/src/utils/FileUtils.java @@ -1,5 +1,6 @@ package utils; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -24,7 +25,7 @@ public class FileUtils } catch (IOException e) { - e.printStackTrace(); + GlobalLog.Error(LogFilter.Util, e.getMessage()); } return contentBuilder.toString(); @@ -35,13 +36,18 @@ public class FileUtils { ArrayList items = new ArrayList(); + File tmpDir = new File(startingDir); + if(!tmpDir.exists()) + return new ArrayList(); + + try { Files.find(Paths.get(startingDir), 999, (path, attributes) -> attributes.isRegularFile()).forEach(items::add); } catch (IOException e) { - e.printStackTrace(); + GlobalLog.Error(LogFilter.Util, e.getMessage()); } return items;