internal void RequestModList(NetworkMessageInfo info) { if (Network.isServer) { SendRequiredModList(Gadgets.ListAllGadgetInfos().Where(x => x.Gadget.Enabled && x.Attribute.RequiredOnClients).Select(x => x.Attribute.Name + ":" + x.Gadget.GetModVersionString()).Aggregate(new StringBuilder(), (x, y) => { if (x.Length > 0) { x.Append(","); } x.Append(y); return(x); }).ToString(), info); } else { GadgetCore.CoreLogger.Log("Host is requesting local mod list. Sending..."); GadgetNetwork.connectTime = Time.realtimeSinceStartup; if (view == null) { view = GetComponent <NetworkView>(); } view.RPC("SendRequiredModList", RPCMode.Server, Gadgets.ListAllGadgetInfos().Where(x => x.Gadget.Enabled && x.Attribute.RequiredOnClients).Select(x => x.Attribute.Name + ":" + x.Gadget.GetModVersionString()).Aggregate(new StringBuilder(), (x, y) => { if (x.Length > 0) { x.Append(","); } x.Append(y); return(x); }).ToString()); } }
public static void Prefix(GameScript __instance) { InstanceTracker.GameScript = __instance; GadgetCore.GenerateSpriteSheet(); GadgetUtils.SafeCopyTexture(__instance.TileManager.GetComponent <ChunkWorld>().Texture, 0, 0, 0, 0, 128, 128, GadgetCoreAPI.spriteSheet, 0, 0, 0, 0); __instance.TileManager.GetComponent <ChunkWorld>().Texture = GadgetCoreAPI.spriteSheet; __instance.WallManager.GetComponent <ChunkWorld>().Texture = GadgetCoreAPI.spriteSheet; GameObject gadgetHookScriptHolder = new GameObject("Gadget Hook Script Holder"); foreach (GadgetInfo mod in Gadgets.ListAllGadgetInfos()) { gadgetHookScriptHolder.AddComponent <GadgetHookScript>().Mod = mod; } }
private bool IsRestartNeeded() { if (unpackedMods.Count > 0) { return(true); } int umfModCount = umfModEntries?.Count ?? 0; foreach (GadgetInfo gadget in Gadgets.ListAllGadgetInfos()) { if (GadgetCoreConfig.enabledGadgets[gadget.Attribute.Name] != gadget.Gadget.Enabled) { return(true); } if (originalConfig.ContainsKey(gadget.Attribute.Name)) { if (!originalConfig[gadget.Attribute.Name].Equals(File.ReadAllText(GadgetPaths.ConfigsPath + "/" + Gadgets.GetGadgetInfo(modIndex).Mod.Name + ".ini"))) { return(true); } } } if (GadgetCoreAPI.GetUMFAPI() != null) { if (!File.Exists(GadgetCoreAPI.GetUMFAPI().GetDisabledModsFile())) { File.Create(GadgetCoreAPI.GetUMFAPI().GetDisabledModsFile()).Dispose(); } string[] disabledMods = File.ReadAllLines(GadgetCoreAPI.GetUMFAPI().GetDisabledModsFile()).Where(x => !string.IsNullOrEmpty(x)).ToArray(); for (int i = 0; i < umfModEntries.Count; i++) { if (wasEnabled.ContainsKey(umfModEntries[i].Name)) { if (wasEnabled[umfModEntries[i].Name] == disabledMods.Contains(umfModEntries[i].Name)) { return(true); } } if (originalConfig.ContainsKey(umfModEntries[i].Name)) { if (!originalConfig[umfModEntries[i].Name].Equals(File.ReadAllText(GadgetCoreAPI.GetUMFAPI().GetConfigsPath() + "/" + umfModEntries[i].Name + ".ini"))) { return(true); } } } } return(false); }
private static void VerifyCompatible(NetworkPlayer pl) { if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients)) { GadgetCore.CoreLogger.LogWarning("Disconnecting client " + pl.ipAddress + " due to timout! You can try raising NetworkTimeout in the config."); Network.CloseConnection(pl, true); } }
internal void SendRequiredModList(string modList, NetworkMessageInfo info) { try { bool isCompatible = true; int modCount = 0; string[][] splitModList = string.IsNullOrEmpty(modList) ? new string[0][] : modList.Split(',').Select(x => x.Split(':')).ToArray(); foreach (GadgetInfo mod in Gadgets.ListAllGadgetInfos().Where(x => x.Gadget.Enabled && x.Attribute.RequiredOnClients)) { modCount++; int[] hostVersionNums = mod.Gadget.GetModVersionString().Split('.').Select(x => int.Parse(x)).ToArray(); int[] clientVersionNums = splitModList.SingleOrDefault(x => x[0] == mod.Attribute.Name)?[1].Split('.').Select(x => int.Parse(x)).Take(4).ToArray(); if (clientVersionNums == null) { isCompatible = false; break; } hostVersionNums = hostVersionNums.Concat(Enumerable.Repeat(0, 4 - hostVersionNums.Length)).ToArray(); clientVersionNums = clientVersionNums.Concat(Enumerable.Repeat(0, 4 - clientVersionNums.Length)).ToArray(); if (!((mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MAJOR && clientVersionNums[0] == hostVersionNums[0] && (clientVersionNums[1] > hostVersionNums[1] || (clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))))) || (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MINOR && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))) || (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.NONBREAKING && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]) || (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.BUGFIX && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] == hostVersionNums[3]))) { isCompatible = false; break; } } if (isCompatible && modCount != splitModList.Length) { isCompatible = false; } if (isCompatible) { if (string.IsNullOrEmpty(info.sender.ipAddress)) { GadgetCore.CoreLogger.Log("Self-connection succesfully established and identified."); ReceiveIDMatrixData(GadgetNetwork.GenerateIDMatrixData()); } else { GadgetCore.CoreLogger.Log("A client connected with compatible mods: " + info.sender.ipAddress); view.RPC("ReceiveIDMatrixData", info.sender, GadgetNetwork.GenerateIDMatrixData()); } } else { GadgetCore.CoreLogger.LogWarning("A client tried to connect with incompatible mods: " + info.sender.ipAddress + Environment.NewLine + modList); if (Network.isServer) { Network.CloseConnection(info.sender, true); } else { Network.Disconnect(); } } } catch (Exception e) { GadgetCore.CoreLogger.LogWarning("The following error occured processing an incoming client's mod list: " + info.sender.ipAddress + Environment.NewLine + modList + Environment.NewLine + e.ToString()); if (Network.isServer) { Network.CloseConnection(info.sender, true); } else { Network.Disconnect(); } } }
private static void VerifyCompatible(NetworkPlayer pl) { if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients)) { Network.CloseConnection(pl, true); } }
public static bool Prefix(GameScript __instance) { if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() < GadgetNetwork.MatrixTimeout) { if (InstanceTracker.GameScript.gameObject.GetComponent <RPCHooks>() == null) { InstanceTracker.GameScript.gameObject.AddComponent <RPCHooks>(); } RPCHooks.InitiateGadgetNetwork(); __instance.StartCoroutine(WaitAndTryAgain(__instance)); return(false); } else { if (GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients)) { GadgetCore.CoreLogger.LogWarning("Disconnecting from server due to timout! You can try raising NetworkTimeout in the config."); Network.Disconnect(); return(false); } return(true); } }
public static bool Prefix(GameScript __instance) { if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() < GadgetNetwork.MatrixTimeout) { if (InstanceTracker.GameScript.gameObject.GetComponent <RPCHooks>() == null) { InstanceTracker.GameScript.gameObject.AddComponent <RPCHooks>(); } __instance.StartCoroutine(WaitAndTryAgain(__instance)); return(false); } else { if (GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients)) { Network.Disconnect(); return(false); } return(true); } }
internal void SendRequiredModList(string modList, NetworkMessageInfo info) { GadgetCore.CoreLogger.Log("Client has sent local mod list. Processing..."); try { bool isCompatible = true; List <string> incompatibleReasons = new List <string>(); HashSet <string> handledGadgets = new HashSet <string>(); string[][] splitModList = string.IsNullOrEmpty(modList) ? new string[0][] : modList.Split(',').Select(x => x.Split(':')).ToArray(); foreach (GadgetInfo mod in Gadgets.ListAllGadgetInfos().Where(x => x.Gadget.Enabled && x.Attribute.RequiredOnClients)) { handledGadgets.Add(mod.Attribute.Name); string clientVersion = splitModList.SingleOrDefault(x => x[0] == mod.Attribute.Name)?[1]; if (clientVersion == null) { isCompatible = false; incompatibleReasons.Add($"The Gadget '{mod.Attribute.Name}' (From the mod '{mod.ModName}') is not present on the client"); continue; } int[] clientVersionNums = clientVersion.Split('.').Select(x => int.Parse(x)).Take(4).ToArray(); int[] hostVersionNums = mod.Gadget.GetModVersionString().Split('.').Select(x => int.Parse(x)).ToArray(); hostVersionNums = hostVersionNums.Concat(Enumerable.Repeat(0, 4 - hostVersionNums.Length)).ToArray(); clientVersionNums = clientVersionNums.Concat(Enumerable.Repeat(0, 4 - clientVersionNums.Length)).ToArray(); if (!((mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MAJOR && clientVersionNums[0] == hostVersionNums[0] && (clientVersionNums[1] > hostVersionNums[1] || (clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))))) || (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MINOR && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))) || (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.NONBREAKING && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]) || (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.BUGFIX && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] == hostVersionNums[3]))) { isCompatible = false; incompatibleReasons.Add($"The Gadget '{mod.Attribute.Name}' (From the mod '{mod.ModName}') is of incompatible versions: Host: {mod.Gadget.GetModVersionString()}, Client: {clientVersion}"); continue; } } if (handledGadgets.Count != splitModList.Length) { isCompatible = false; foreach (string[] modEntry in splitModList.Where(x => !handledGadgets.Contains(x[0]))) { incompatibleReasons.Add($"The Gadget '{modEntry[0]}' (From an unknown mod) is present on the client, but not on the host"); } } if (isCompatible) { if (info.Equals(serverNMI)) { GadgetCore.CoreLogger.Log("Self-connection succesfully established and identified."); ReceiveIDMatrixData(GadgetNetwork.GenerateIDMatrixData()); } else { GadgetCore.CoreLogger.Log("A client connected with compatible mods: " + info.sender.ipAddress); string matrixData = GadgetNetwork.GenerateIDMatrixData(); if (matrixData.Length <= 4096) { GadgetCore.CoreLogger.Log("Sending ID Matrix data as a single block..."); view.RPC("ReceiveIDMatrixData", info.sender, matrixData); } else { string[] splitMatrixData = matrixData.SplitOnLength(MaxChunkSize).ToArray(); GadgetCore.CoreLogger.Log($"Sending ID Matrix data as {splitMatrixData.Length} chunks..."); for (int i = 0; i < splitMatrixData.Length; i++) { view.RPC("ReceiveIDMatrixDataChunk", info.sender, splitMatrixData[i], i, splitMatrixData.Length); } } } } else { GadgetCore.CoreLogger.LogWarning("A client tried to connect with incompatible mods: " + info.sender.ipAddress + Environment.NewLine + " - " + incompatibleReasons.Concat(Environment.NewLine + " - ")); if (Network.isServer) { DisconnectWithMessage(info.sender, "Your mods are incompatible with the server:" + Environment.NewLine + " - " + incompatibleReasons.Concat(Environment.NewLine + " - ")); } else { Network.Disconnect(); } } } catch (Exception e) { GadgetCore.CoreLogger.LogWarning("The following error occured processing an incoming client's mod list: " + info.sender.ipAddress + Environment.NewLine + modList + Environment.NewLine + e.ToString()); if (Network.isServer) { DisconnectWithMessage(info.sender, "An error occured processing your mod list:" + Environment.NewLine + modList + Environment.NewLine + e.ToString()); } else { Network.Disconnect(); } } }