/// MINECRAFT /// Reading and Parsing for minecraft /// MINECRAFT public static List <ItemPair> parseMinecraft(Settings settings, DualDictionary <String, String> mappings, Dictionary <String, double> ratios) { List <ItemPair> items = new List <ItemPair>(); String fullPath = Path.Combine(settings.getMcPath(), "toFactorio.dat"); while (true) { try { using (FileStream Fs = new FileStream(fullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None, 100)) { break; } } catch (IOException) { Thread.Sleep(100); } } FileStream fs = new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); StreamReader sr = new StreamReader(fs, Encoding.Default); while (!sr.EndOfStream) { string proc = sr.ReadLine(); string[] temp = proc.Split('~'); int count = 0; if (ratios.Count > 0) { double readNum = Double.Parse(temp[1]) * ratios[temp[0]];; count = (int)Math.Round(readNum, MidpointRounding.AwayFromZero); } else { count = (int)Double.Parse(temp[1]); } items.Add(new ItemPair(temp[0], count)); } sr.Close(); File.WriteAllText(fullPath, string.Empty); //Remap Items to the opposing item for (int i = 0; i < items.Count; i++) { try { items[i].name = mappings.minecraft[items[i].name]; } catch (Exception e) { PrintErrorInfo(e); continue; } } return(items); }
public static List <ItemPair> parseFactrio(Settings settings, DualDictionary <String, String> mappings, Dictionary <String, double> ratios) { List <ItemPair> items = new List <ItemPair>(); String fullPath = ""; FileStream fs = new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); StreamReader sr = new StreamReader(fs, Encoding.Default); while (!sr.EndOfStream) { string proc = sr.ReadLine(); string[] temp = proc.Split(':'); int count = 0; if (ratios.Count > 0) { double readNum = Double.Parse(temp[1]) * ratios[temp[0]];; count = (int)Math.Round(readNum, MidpointRounding.AwayFromZero); } else { count = (int)Double.Parse(temp[1]); } int containsTest = pairContains(items, temp[0]); if (containsTest != -1) { if (items[containsTest].count < 64) { int remainder = 64 - items[containsTest].count; if (remainder > 0) { items[containsTest].count += remainder; count -= remainder; } } if ((64 - count) < 0) { items.Add(new ItemPair(temp[0], 64)); int remain = Math.Abs(64 - count); while (remain > 0) { if (remain > 64) { items.Add(new ItemPair(temp[0], 64)); remain -= 64; } else { items.Add(new ItemPair(temp[0], remain)); remain -= 64; } } } else { items.Add(new ItemPair(temp[0], Int32.Parse(temp[1]))); } } else { if ((64 - count) < 0) { items.Add(new ItemPair(temp[0], 64)); int remain = Math.Abs(64 - count); while (remain > 0) { if (remain > 64) { items.Add(new ItemPair(temp[0], 64)); remain -= 64; } else { items.Add(new ItemPair(temp[0], remain)); remain -= 64; } } } else { items.Add(new ItemPair(temp[0], Int32.Parse(temp[1]))); } //items.Add(new ItemPair(temp[0], Int32.Parse(temp[1]))); } StreamWriter sw = new StreamWriter(fs); sw.WriteLine(""); } //Remap Items to the opposing item for (int i = 0; i < items.Count; i++) { items[i].name = mappings.facotrio[items[i].name]; } return(items); }
public static async System.Threading.Tasks.Task <List <ItemPair> > parseVanillaMinecraft(Settings settings, DualDictionary <String, String> mappings, Dictionary <String, double> ratios, RCON rcon) { String RCON_Output = await rcon.SendCommandAsync("execute as @e[tag=SendChest] at @s store result entity @s ArmorItems[3].tag.ClearItems int 1 run data get block ~ ~ ~ Items"); /// ///This section of regex is mostly trial and error. ///It seems to break if too much is thrown at it at once however. /// String toFactorioString = ""; if (RCON_Output != "") { var regex = new Regex(@"^.*?(?<=has the following block data: \[)|(?=\]-?[0-9]*, -?[0-9]*, -?[0-9]* has the following block data: \[).*?(?<=has the following block data: \[)|\]$", RegexOptions.Compiled); var regex2 = new Regex(@"{([^{}]+|(?<Level>{)|(?<-Level>}))+(?(Level)(?!))}", RegexOptions.Compiled); //var regex3 = new Regex(@",(?![^[]]*\))",RegexOptions.Compiled); <-- This regex wouldn't cooperate String[] SplitOutput = regex.Split(RCON_Output); String[][][] ParsedOutput = new String[SplitOutput.Length - 2][][]; for (int i = 0; i < (SplitOutput.Length - 2); i++) { String MatchString = SplitOutput[i + 1]; MatchCollection MatchOutput2 = regex2.Matches(MatchString); ParsedOutput[i] = new String[MatchOutput2.Count][]; for (int j = 0; j < MatchOutput2.Count; j++) { String MatchString3 = MatchOutput2[j].ToString(); String[] SplitOutput3 = MatchString3.Split(new[] { ',' }, 4); //String[] SplitOutput3 = regex3.Split(MatchString3.Substring(1,MatchString3.Length-2)); ParsedOutput[i][j] = new String[SplitOutput3.Length]; for (int k = 0; k < (SplitOutput3.Length); k++) { ParsedOutput[i][j][k] = SplitOutput3[k].Trim(); } } } StringBuilder str = new StringBuilder(); for (int i = 0; i < ParsedOutput.Length; i++) { for (int j = 0; j < ParsedOutput[i].Length; j++) { if (ParsedOutput[i][j].Length == 3) { str.Append(ParsedOutput[i][j][1].Remove(0, 5).TrimEnd('"') + "~" + ParsedOutput[i][j][2].Remove(0, 7).TrimEnd('}').TrimEnd('b')); } else { str.Append(ParsedOutput[i][j][1].Remove(0, 5).TrimEnd('"') + ParsedOutput[i][j][3].Remove(ParsedOutput[i][j][3].Length - 1, 1).Remove(0, 5) + "~" + ParsedOutput[i][j][2].Remove(0, 7).TrimEnd('b')); } str.AppendLine(); } } toFactorioString = str.ToString().TrimEnd(Environment.NewLine.ToCharArray()); } List <ItemPair> items = new List <ItemPair>(); String[] temp7 = toFactorioString.Split(Environment.NewLine.ToCharArray()); foreach (String stringy3 in temp7) { if (string.IsNullOrWhiteSpace(stringy3) == false) { string[] temp = stringy3.Split('~'); int count = 0; if (ratios.Count > 0) { double readNum = Double.Parse(temp[1]) * ratios[temp[0]];; count = (int)Math.Round(readNum, MidpointRounding.AwayFromZero); } else { count = (int)Double.Parse(temp[1]); } items.Add(new ItemPair(temp[0], count)); } } //Remap Items to the opposing item for (int i = 0; i < items.Count; i++) { try { items[i].name = mappings.minecraft[items[i].name]; } catch (Exception e) { PrintErrorInfo(e); continue; } } return(items); }
static void Main(string[] args) { /* * I'm really not sure whether the servers close properly when the bridge closes, * so these lines are here to make sure nothing weird happens. */ String Previous_Factorio_Server_PID = File.ReadAllText("Factorio_Server_PID.txt"); String Previous_Minecraft_Server_PID = File.ReadAllText("Minecraft_Server_PID.txt"); if (Previous_Factorio_Server_PID != "") { KillPreviousServer(Int32.Parse(Previous_Factorio_Server_PID), "Factorio"); File.WriteAllText("Factorio_Server_PID.txt", string.Empty); } if (Previous_Minecraft_Server_PID != "") { KillPreviousServer(Int32.Parse(Previous_Minecraft_Server_PID), "Minecraft"); File.WriteAllText("Minecraft_Server_PID.txt", string.Empty); } /* * Input and checking for settings file. * This should probably not immedantly check but prompt the user with the current settings and if they would like to change them */ Console.ForegroundColor = ConsoleColor.Cyan; BridgeConsoleWriteLine("Starting Up!"); BridgeConsoleWriteLine("To change settings, enter 1, otherwise press any key other to continue"); string choice = Console.ReadLine(); Settings settings = new Settings(); string startupDoc = Path.Combine(Environment.CurrentDirectory, "settings.json"); if (!File.Exists(startupDoc) || choice.Equals("1")) { FileStream fs1 = new FileStream(startupDoc, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite); StreamReader sr = new StreamReader(fs1, Encoding.Default); // string input = ""; while (!sr.EndOfStream) { input += sr.ReadLine(); } settings = JsonConvert.DeserializeObject <Settings>(input); sr.Close(); fs1.Close(); FileStream fs = new FileStream(startupDoc, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); // String TempInput = ""; BridgeConsoleWriteLine("To leave a setting unchanged from the previous value, just hit enter without typing anything."); BridgeConsoleWriteLine("Please enter the item mappings file name (default \"item_mappings.txt\")"); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setItemMappingsFile(TempInput); } BridgeConsoleWriteLine("Please enter Minecraft Type (0=Forge,1=Vanilla 18w46a): "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setMcType(Int32.Parse(TempInput)); } BridgeConsoleWriteLine("Use experimental IO? (true/false): "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setExperimentalIO(bool.Parse(TempInput)); } BridgeConsoleWriteLine("Please enter Minecraft Location (Root of the Directory): "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setMcPath(TempInput); } if (settings.getMcType() != 0) { BridgeConsoleWriteLine("Please enter the IP Address of the Minecraft Server: "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setMcIpAddress(TempInput); } BridgeConsoleWriteLine("Please enter Minecraft RCON Port Number: "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setMcPort(Int32.Parse(TempInput)); } BridgeConsoleWriteLine("Please enter Minecraft RCON password: "******"") { settings.setMcRconPass(TempInput); } if (settings.getExperimentalIO() == true) { BridgeConsoleWriteLine("Please enter the Java to run the Minecraft server with (likely just \"java\" will work):"); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setMcServerJava(TempInput); } BridgeConsoleWriteLine("Please enter Minecraft server location:"); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setMcServerDirectory(TempInput); } BridgeConsoleWriteLine("Please enter Minecraft server parameters:"); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setMcServerParams(TempInput); } } } BridgeConsoleWriteLine("Please enter Factorio Data Path (Root of the Directory): "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setFacotrioPath(TempInput); } BridgeConsoleWriteLine("Please enter the IP Address of the Factorio Server: "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setFactorioIpAddress(TempInput); } BridgeConsoleWriteLine("Please enter Factorio RCON Port Number: "); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setFactorioPort(Int32.Parse(TempInput)); } BridgeConsoleWriteLine("Please enter Factorio RCON password: "******"") { settings.setFactorioRconPass(TempInput); } if (settings.getExperimentalIO() == true) { BridgeConsoleWriteLine("Please enter path to Factorio server:"); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setFactorioServerPath(TempInput); } BridgeConsoleWriteLine("Please enter Factorio server parameters:"); TempInput = Console.ReadLine(); if (TempInput != "") { settings.setFactorioServerParams(TempInput); } } string output = JsonConvert.SerializeObject(settings); StreamWriter sw = new StreamWriter(fs, Encoding.Default); sw.WriteLine(output); sw.Close(); //sr.Close(); } else { FileStream fs = new FileStream(startupDoc, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite); StreamReader sr = new StreamReader(fs, Encoding.Default); string input = ""; while (!sr.EndOfStream) { input += sr.ReadLine(); } settings = JsonConvert.DeserializeObject <Settings>(input); } /* * Load in the item mappings file. */ DualDictionary <String, String> itemMappings = new DualDictionary <String, String>(); Dictionary <String, double> minecraftRatios = new Dictionary <String, double>(); Dictionary <String, double> factorioRatios = new Dictionary <String, double>(); //Open up the file stream for the item mappings string itemMappingsPath = Path.Combine(Environment.CurrentDirectory, settings.getItemMappingsFile()); FileStream fileStream = new FileStream(itemMappingsPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read); StreamReader streamReader = new StreamReader(fileStream, Encoding.Default); //This loops needs to do a couple of things. //The first is it needs to read in the mappings into the DualDictionary for better translation of names. //The second it needs to bind the item ratios to their respective lists. while (!streamReader.EndOfStream) { //Item Name Mappings first String readString = streamReader.ReadLine(); if (readString.Contains("#") || readString.Equals("") || readString.Equals("\n")) { continue; } String[] split = readString.Split('='); itemMappings.Add(split[0], split[1]); //Split the string again to get the ratios if (split.Length > 2) { String[] ratios = split[2].Split(':'); minecraftRatios.Add(split[0], Double.Parse(ratios[0])); factorioRatios.Add(split[1], Double.Parse(ratios[1])); } } streamReader.Close(); fileStream.Close(); /* * Open RCON Connection to factorio server * Parse the files and send the data to the approiate game. */ //var rcon = new RCON(IPAddress.Parse(settings.getFactorioIPAddress()), (ushort)settings.getFactorioPort(), settings.getFactorioRconPass() ); if (settings.getMcType() == 0) { BridgeConsoleWriteLine("Found settings. Beginning transfer."); var rcon = new RCON(IPAddress.Parse(settings.getFactorioIPAddress()), (ushort)settings.getFactorioPort(), settings.getFactorioRconPass()); while (true) { try { List <ItemPair> factorioItems = parseFactorio(settings, itemMappings, factorioRatios); List <ItemPair> minecraftItems = parseMinecraft(settings, itemMappings, minecraftRatios); sendToFactorioRCON(minecraftItems, rcon); sendToMinecraft(factorioItems, settings); Thread.Sleep(1000); } catch (Exception e) { PrintErrorInfo(e); continue; } } } else { /* * Since all three programs run in the same window, each is color coded and labelled to make it legible: * Bridge: Cyan * Factorio: Red * Minecraft: Green * * I'm planning on adding an option to change the colors later. */ if (settings.getExperimentalIO() == true) { BridgeConsoleWriteLine("Found settings."); BridgeConsoleWriteLine("Starting Factorio server..."); Process FactorioServer = new Process(); /* * These two lines are the parameters for the Factorio server */ FactorioServer.StartInfo.FileName = settings.getFactorioServerPath(); FactorioServer.StartInfo.Arguments = settings.getFactorioServerParams(); FactorioServer.StartInfo.CreateNoWindow = false; FactorioServer.StartInfo.WorkingDirectory = settings.getMcServerDirectory(); FactorioServer.StartInfo.ErrorDialog = false; FactorioServer.StartInfo.UseShellExecute = false; FactorioServer.StartInfo.RedirectStandardError = true; FactorioServer.StartInfo.RedirectStandardOutput = true; //FactorioServer.StartInfo.RedirectStandardInput = true; String FactorioServerLog = ""; FactorioServer.OutputDataReceived += new DataReceivedEventHandler ( (sender, args2) => { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[Factorio] " + args2.Data); FactorioServerLog = args2.Data; } ); FactorioServer.ErrorDataReceived += new DataReceivedEventHandler ( (sender, args2) => { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[Factorio Error] " + args2.Data); FactorioServerLog = args2.Data; } ); FactorioServer.Start(); //Stream FactorioInputStream = FactorioServer.StandardInput. //StreamWriter FactorioInputWriter = FactorioServer.StandardInput; FactorioServer.BeginOutputReadLine(); FactorioServer.BeginErrorReadLine(); File.WriteAllText("Factorio_Server_PID.txt", FactorioServer.Id.ToString()); bool FactorioServerLoading = true; while (FactorioServerLoading) { if (FactorioServerLog.Contains("Starting RCON interface at port " + settings.getFactorioPort())) { FactorioServerLoading = false; } } var rcon = new RCON(IPAddress.Parse(settings.getFactorioIPAddress()), (ushort)settings.getFactorioPort(), settings.getFactorioRconPass()); BridgeConsoleWriteLine("Factorio server loaded!"); BridgeConsoleWriteLine("Starting Minecraft server..."); Process MinecraftServer = new Process(); /* * These two lines are the parameters for the Minecraft server */ MinecraftServer.StartInfo.FileName = settings.getMcServerJava(); MinecraftServer.StartInfo.Arguments = settings.getMcServerParams(); MinecraftServer.StartInfo.CreateNoWindow = false; MinecraftServer.StartInfo.WorkingDirectory = settings.getMcServerDirectory(); MinecraftServer.StartInfo.ErrorDialog = false; MinecraftServer.StartInfo.UseShellExecute = false; MinecraftServer.StartInfo.RedirectStandardError = true; MinecraftServer.StartInfo.RedirectStandardOutput = true; MinecraftServer.StartInfo.RedirectStandardInput = true; String MinecraftServerLog = ""; MinecraftServer.OutputDataReceived += new DataReceivedEventHandler ( (sender, args2) => { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("[Minecraft] " + args2.Data); MinecraftServerLog = args2.Data; } ); MinecraftServer.ErrorDataReceived += new DataReceivedEventHandler ( (sender, args2) => { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("[Minecraft Error] " + args2.Data); MinecraftServerLog = args2.Data; } ); MinecraftServer.Start(); StreamWriter MinecraftInputWriter = MinecraftServer.StandardInput; MinecraftServer.BeginOutputReadLine(); MinecraftServer.BeginErrorReadLine(); File.WriteAllText("Minecraft_Server_PID.txt", MinecraftServer.Id.ToString()); bool MinecraftServerLoading = true; while (MinecraftServerLoading) { if (MinecraftServerLog.Contains("RCON running on " + settings.getMcIPAddress() + ":" + settings.getMcPort())) { MinecraftServerLoading = false; } } var rcon2 = new RCON(IPAddress.Parse(settings.getMcIPAddress()), (ushort)settings.getMcPort(), settings.getMcRconPass()); BridgeConsoleWriteLine("Minecraft server loaded!"); BridgeConsoleWriteLine("Beginning transfer."); String BridgeInput = ""; System.Threading.Tasks.Task.Run (async() => { while (true) { if (Console.IsInputRedirected == false) { //BridgeInput = await Console.In.ReadLineAsync(); BridgeInput = await Console.In.ReadLineAsync(); //BridgeInput = Console.ReadLine(); } } } ); while (true) { try { if (String.IsNullOrEmpty(BridgeInput) == false) { BridgeConsoleWriteLine(BridgeInput); BridgeInput = ""; } List <ItemPair> factorioItems = parseFactorio(settings, itemMappings, factorioRatios); List <ItemPair> minecraftItems = parseVanillaMinecraft(settings, itemMappings, minecraftRatios, rcon2).Result; sendToFactorioRCON(minecraftItems, rcon); //sendToFactorioExperimentalIO(minecraftItems, FactorioInputWriter); sendToVanillaExperimentalIO(factorioItems, settings, MinecraftInputWriter); //sendToFactorioExperimentalIO(minecraftItems, FactorioServer.StandardInput); //sendToVanillaExperimentalIO(factorioItems, settings, MinecraftServer.StandardInput); Thread.Sleep(1000); } catch (Exception e) { PrintErrorInfo(e); continue; } } } else { BridgeConsoleWriteLine("Found settings. Beginning transfer."); var rcon = new RCON(IPAddress.Parse(settings.getFactorioIPAddress()), (ushort)settings.getFactorioPort(), settings.getFactorioRconPass()); var rcon2 = new RCON(IPAddress.Parse(settings.getMcIPAddress()), (ushort)settings.getMcPort(), settings.getMcRconPass()); while (true) { try { List <ItemPair> factorioItems = parseFactorio(settings, itemMappings, factorioRatios); List <ItemPair> minecraftItems = parseVanillaMinecraft(settings, itemMappings, minecraftRatios, rcon2).Result; sendToFactorioRCON(minecraftItems, rcon); sendToVanillaRCON(factorioItems, settings, rcon2); Thread.Sleep(1000); } catch (Exception e) { PrintErrorInfo(e); continue; } } } } }
static void Main(string[] args) { /* * Input and checking for settings file. * This should probably not immedantly check but prompt the user with the current settings and if they would like to change them */ Console.WriteLine("Starting Up!"); Console.WriteLine("To change settings, enter 1, otherwise press any key other to continue."); string choice = Console.ReadLine(); Settings settings = new Settings(); string startupDoc = Path.Combine(Environment.CurrentDirectory, "settings.json"); if (!File.Exists(startupDoc) || choice.Equals("1")) { FileStream fs = new FileStream(startupDoc, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); StreamWriter sw = new StreamWriter(fs, Encoding.Default); Console.WriteLine("Please enter Minecraft Location (Root of the Directory): "); settings.setMcPath(Console.ReadLine()); Console.WriteLine("Please enter Factorio Server Path (Root of the Directory): "); settings.setFacotrioPath(Console.ReadLine()); Console.WriteLine("Please enter the IP Address of the Factorio Server: "); settings.setIpAddress(Console.ReadLine()); Console.WriteLine("Please enter RCON Port Number: "); settings.setPort(Int32.Parse(Console.ReadLine())); Console.WriteLine("Please enter RCON password: "******""; while (!sr.EndOfStream) { input += sr.ReadLine(); } settings = JsonConvert.DeserializeObject <Settings>(input); } /* * Load in the item mappings file. */ DualDictionary <String, String> itemMappings = new DualDictionary <String, String>(); Dictionary <String, double> minecraftRatios = new Dictionary <String, double>(); Dictionary <String, double> factorioRatios = new Dictionary <String, double>(); //Open up the file stream for the item mappings string itemMappingsPath = Path.Combine(Environment.CurrentDirectory, "item_mappings.txt"); FileStream fileStream = new FileStream(itemMappingsPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read); StreamReader streamReader = new StreamReader(fileStream, Encoding.Default); //This loops needs to do a couple of things. //The first is it needs to read in the mappings into the DualDictionary for better translation of names. //The second it needs to bind the item ratios to their respective lists. while (!streamReader.EndOfStream) { //Item Name Mappings first String readString = streamReader.ReadLine(); if (readString.Contains("#") || readString.Equals("") || readString.Equals("\n")) { continue; } String[] split = readString.Split('='); itemMappings.Add(split[0], split[1]); //Split the string again to get the ratios if (split.Length > 2) { String[] ratios = split[2].Split(':'); minecraftRatios.Add(split[0], Double.Parse(ratios[0])); factorioRatios.Add(split[1], Double.Parse(ratios[1])); } } streamReader.Close(); fileStream.Close(); /* * Open RCON Connection to factorio server * Parse the files and send the data to the approiate game. */ Console.WriteLine("Found settings. Beginning transfer."); var rcon = new RCON(IPAddress.Parse(settings.getIPAddress()), (ushort)settings.getPort(), settings.getRconPass()); while (true) { try { List <ItemPair> factorioItems = parseFactrio(settings, itemMappings, factorioRatios); List <ItemPair> minecraftItems = parseMinecraft(settings, itemMappings, minecraftRatios); sendToFactorio(minecraftItems, rcon); sendToMinecraft(factorioItems, settings); Thread.Sleep(1000); } catch (Exception e) { Console.WriteLine("Something went wrong. Moving past error."); Console.WriteLine(e.Message); continue; } } }