// Hook RPC_PeerInfo to check in front of the original method private static void ZNet_RPC_PeerInfo(On.ZNet.orig_RPC_PeerInfo orig, ZNet self, ZRpc rpc, ZPackage pkg) { if (ZNet.instance.IsServerInstance() || ZNet.instance.IsLocalInstance()) { try { var clientVersion = new ModuleVersionData(clientVersions[rpc.GetSocket().GetEndPointString()]); var serverVersion = new ModuleVersionData(GetEnforcableMods().ToList()); // Remove from list clientVersions.Remove(rpc.GetSocket().GetEndPointString()); // Compare and disconnect when not equal if (!clientVersion.Equals(serverVersion)) { rpc.Invoke("Error", 3); return; } } catch (EndOfStreamException) { Logger.LogError("Reading beyond end of stream. Probably client without Jotunn tried to connect."); // Client did not send appended package, just disconnect with the incompatible version error rpc.Invoke("Error", 3); return; } catch (KeyNotFoundException ex) { // Vanilla client trying to connect? // Check mods, if there are some installed on the server which need also to be on the client if (GetEnforcableMods().Any(x => x.Item3 == CompatibilityLevel.EveryoneMustHaveMod)) { // There is a mod, which needs to be client side too // Lets disconnect the vanilla client with Incompatible Version message rpc.Invoke("Error", 3); return; } } } else { // If we got this far on client side, clear lastServerVersion again lastServerVersion = null; } // call original method orig(self, rpc, pkg); }
private static bool Prefix(ref ZNet __instance, ZRpc rpc, ZPackage pkg) { if (__instance.IsServer()) { string self = ""; if (pkg.Size() > 32) { pkg.SetPos(pkg.Size() - 32 - 1); if (pkg.ReadByte() == (byte)32) { pkg.SetPos(pkg.GetPos() - 1); self = pkg.ReadString(); } } ZLog.Log((object)("[AntiMods]: Got client hash: " + self + "\nmine: " + VACPlugin.PluginsHash)); ZLog.LogWarning("Plugins Hash is Equals: " + !self.Equals(VACPlugin.PluginsHash) + " ForceMods: " + VACPlugin.forcesamemods.Value); ZLog.LogWarning("Is in Admin List: " + !ZNet.instance.m_adminList.Contains(rpc.GetSocket().GetHostName()) + "Admin Bypass: "******"[AntiMods]: Kicking Client: " + rpc.GetSocket().GetEndPointString() + " (incompatible mods)")); rpc.Invoke("Error", (object)num); return(false); } ZLog.Log((object)("[AntiMods]: Accepting Client: " + rpc.GetSocket().GetEndPointString())); } return(true); }
public static void CharacterUpdate(ZRpc rpc, ZPackage data) { // Are we the server? Update the character. if (ZNet.instance.IsServer()) { Debug.Log("Client->Server CharacterUpdate"); string hostName = rpc.GetSocket().GetHostName(); ZNetPeer peer = ZNet.instance.GetPeerByHostName(hostName); string PlayerNameRaw = peer.m_playerName; string PlayerName = ""; if (WorldofValheimServerSideCharacters.AllowMultipleCharacters.Value) { PlayerName = Regex.Replace(PlayerNameRaw, @"<[^>]*>", String.Empty); } else { PlayerName = "Single_Character_Mode"; } string CharacterLocation = Util.GetCharacterPath(hostName, PlayerName); Debug.Log($"Saving character from SteamID {hostName}."); Util.WriteCharacter(CharacterLocation, Util.Decompress(data).GetArray()); return; } // Are we the client? Send our character. Debug.Log("Server->Client CharacterUpdate"); if (Player.m_localPlayer != null) { rpc.Invoke("CharacterUpdate", new object[] { Util.Compress(Game.instance.GetPlayerProfile().Serialize(Player.m_localPlayer, true)) }); return; } }
// ReSharper disable once InconsistentNaming private static void Postfix(int x, int y, bool __result) { if (__result == false) { return; } if (_blockExplore) { return; } if (!Store.IsSharingMap()) { return; } if (_ZNet.IsServer(_ZNet._instance)) { OnClientExplore(null, x, y); } else { var znet = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue() as ZNet; ZRpc server = _ZNet.GetServerRPC(znet); server.Invoke("OnClientExplore", (object)x, (object)y); } }
static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return(true); } string text = __instance.m_input.text; if (text.ToLower().Equals($"{typeof(BepInExPlugin).Namespace.ToLower()} reset")) { context.Config.Reload(); context.Config.Save(); ApplyConfig(); Traverse.Create(__instance).Method("AddString", new object[] { text }).GetValue(); Traverse.Create(__instance).Method("AddString", new object[] { $"{context.Info.Metadata.Name} config reloaded" }).GetValue(); return(false); } if (text.ToLower().StartsWith($"{typeof(BepInExPlugin).Namespace.ToLower()} ")) { ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (serverRPC != null) { serverRPC.Invoke("ServerRewardsConsoleCommand", new object[] { text }); } Traverse.Create(__instance).Method("AddString", new object[] { text }).GetValue(); return(false); } return(true); }
public static IEnumerator Client2(ZRpc rpc) { rpc.Invoke("Client", new object[] { Client.Serialize(rpc.GetSocket().GetHostName()) }); yield return(new WaitForSeconds(1)); }
public static IEnumerator ZoneHandler2(ZRpc rpc) { rpc.Invoke("ZoneHandler", new object[] { ZoneHandler.Serialize(rpc.GetSocket().GetHostName()) }); yield return(new WaitForSeconds(1)); }
private void WindowBuilder(int id) { GUI.DragWindow(new Rect(0, 0, windowWidth.Value, 20)); GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(windowWidth.Value) }); GUILayout.Label(windowTitleText, titleStyle); GUILayout.Label(string.Format(myCurrencyString.Value, string.Format(currencyString.Value, myCurrency)), currencyStyle); float width = windowWidth.Value - 70; float itemWidth = width / packagesPerRow.Value; scrollPosition = GUILayout.BeginScrollView(scrollPosition, new GUILayoutOption[] { GUILayout.Width(windowWidth.Value - 20) }); GUILayout.Space(10); GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(width) }); GUILayout.BeginHorizontal(); for (int i = 0; i < storePackages.Count; i++) { if (i > 0 && i % packagesPerRow.Value == 0) { GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.BeginHorizontal(); } PackageInfo pi = storePackages[i]; string texture = textureDict.ContainsKey(pi.type) ? pi.type : "Common"; GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(itemWidth) }); if (GUILayout.Button(textureDict[texture], new GUILayoutOption[] { GUILayout.Width(itemWidth), GUILayout.Height(itemWidth) })) { if (myCurrency >= pi.price) { ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (serverRPC != null) { Dbgl("Requesting store data"); JsonCommand command = new JsonCommand() { command = "BuyPackage", packageid = pi.id }; string commandJson = JsonUtility.ToJson(command); Dbgl(commandJson); serverRPC.Invoke("SendServerRewardsJSON", new object[] { commandJson }); } } } GUILayout.Label(string.Format(packageString.Value, pi.name, pi.price), labelStyle, new GUILayoutOption[] { GUILayout.Width(itemWidth) }); GUILayout.EndVertical(); } GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); }
private static bool ZNet_RPC_PeerInfo(ZNet __instance, ZRpc rpc, ZPackage pkg) { if (!ZNet.instance.IsClientInstance()) { // Vanilla client trying to connect? if (!ClientVersions.ContainsKey(rpc.GetSocket().GetEndPointString())) { // Check mods, if there are some installed on the server which need also to be on the client if (GetEnforcableMods().Any(x => x.Item3 == CompatibilityLevel.EveryoneMustHaveMod || x.Item3 == CompatibilityLevel.ClientMustHaveMod)) { // There is a mod, which needs to be client side too // Lets disconnect the vanilla client with Incompatible Version message Logger.LogWarning("Disconnecting vanilla client with incompatible version message. " + "There are mods that need to be installed on the client"); rpc.Invoke("Error", (int)ZNet.ConnectionStatus.ErrorVersion); return(false); } } else { var serverData = new ModuleVersionData(GetEnforcableMods().ToList()); var clientData = new ModuleVersionData(ClientVersions[rpc.m_socket.GetEndPointString()]); if (!CompareVersionData(serverData, clientData)) { // Disconnect if mods are not network compatible Logger.LogWarning("RPC_PeerInfo: Disconnecting modded client with incompatible version message. " + "Mods are not compatible"); rpc.Invoke("Error", (int)ZNet.ConnectionStatus.ErrorVersion); return(false); } } } return(true); }
private static void Postfix(ZRpc rpc, ZPackage pkg, ZNet __instance) { if (__instance.IsServer()) { for (var i = 0; i < mapSize * mapSize; i++) { if (getExplored(i)) { var z = new ZPackage(); z.Write(i % mapSize); z.Write(i / mapSize); rpc.Invoke("OnReceiveMapData", (object)z); } } } }
static void Game_SavePlayerProfile(Game __instance, bool setLogoutPoint) { if (ZNet.instance != null && Player.m_localPlayer) { ZRpc serverRpc = ZNet.instance.GetServerRPC(); if (serverRpc != null) { if (Configs.ShowDebugMessages.Value) { UnityEngine.Debug.Log("Saving inventory"); } Inventory playerInventory = Player.m_localPlayer.GetInventory(); ZPackage inventoryPackage = Helper.PackageInventory(Player.m_localPlayer.GetPlayerName(), playerInventory); serverRpc.Invoke("UpdateInventory", new object[] { inventoryPackage }); } } }
private static void ZNet__SendPeerInfo(ZNet __instance, ZRpc rpc) { // Are we the client? Then get out! if (!__instance.IsServer()) { return; } // Ok now that that's done. Lets gogogo Servers! Debug.Log("Server->Client CharacterData"); rpc.Invoke("CharacterData", new object[] { Util.Compress(Util.LoadOrMakeCharacter(rpc.GetSocket().GetHostName())) }); ServerState.Connections.Add(new ServerState.ConnectionData { rpc = rpc }); }
private static void SendPinsToClient(ZRpc client) { if (!Store.IsSharingPin()) { return; } var z = ExplorationDatabase.PackPins(ExplorationDatabase.GetPins()); if (client == null) { OnReceiveInitialDataPin(null, z); } else { client.Invoke("OnReceiveInitialDataPin", (object)z); } }
public static void ValgrindHandshake(ZRpc rpc, int can, string id) { if (ZNet.instance.IsServer()) { } else { int myCan = 0; foreach (var x in Plugin.FindObjectsOfType <GameObject>()) { if (x.name == id) { myCan++; } } rpc.Invoke("ValgrindHandshake", new object[] { myCan, "ErrorCount" }); } }
private void Update() { if (!modEnabled.Value) { return; } if (testing.Value) { if (AedenthornUtils.CheckKeyDown(openUIKey.Value)) { storeOpen = !storeOpen; } return; } if (ZNet.instance && Player.m_localPlayer && !AedenthornUtils.IgnoreKeyPresses(true) && AedenthornUtils.CheckKeyDown(openUIKey.Value)) { Dbgl("Pressed hotkey"); if (storeOpen) { Traverse.Create(GameCamera.instance).Field("m_mouseCapture").SetValue(true); Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; Dbgl("Closing store"); storeOpen = false; } else { ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (serverRPC != null) { Dbgl("Requesting store data"); JsonCommand command = new JsonCommand() { command = "RequestStoreInfo", id = SteamUser.GetSteamID().ToString() }; string commandJson = JsonUtility.ToJson(command); Dbgl(commandJson); serverRPC.Invoke("SendServerRewardsJSON", new object[] { commandJson }); } } } }
public static void ExitServer(ZRpc rpc, ZPackage data) { if (ZNet.instance.IsServer()) { Debug.Log("Client->Server ExitServer"); RPC.CharacterUpdate(rpc, data); rpc.Invoke("ExitServer", new object[] { new ZPackage() }); Debug.Log($"Removing Client {rpc.GetSocket().GetHostName()} from our list"); ServerState.Connections.RemoveAll((ServerState.ConnectionData conn) => conn.rpc.GetSocket() == rpc.GetSocket()); Debug.Log("Connections " + ServerState.Connections.Count.ToString()); return; } Debug.Log("Server->Client ExitServer"); ServerState.Connections.RemoveAll((ServerState.ConnectionData conn) => conn.rpc.GetSocket() == rpc.GetSocket()); ServerState.ClientCanDC = true; }
private static bool ZNet_SendPeerInfo(ZNet __instance, ZRpc rpc, string password) { if (ZNet.instance.IsClientInstance()) { // If there was no server version response, Jötunn is not installed. Cancel if we have mandatory mods if (LastServerVersion == null && GetEnforcableMods().Any(x => x.Item3 == CompatibilityLevel.EveryoneMustHaveMod || x.Item3 == CompatibilityLevel.ServerMustHaveMod)) { Logger.LogWarning("Jötunn is not installed on the server. Client has mandatory mods. Cancelling connection"); rpc.Invoke("Disconnect"); LastServerVersion = new ModuleVersionData(new List <Tuple <string, System.Version, CompatibilityLevel, VersionStrictness> >()).ToZPackage(); ZNet.m_connectionStatus = ZNet.ConnectionStatus.ErrorVersion; return(false); } } return(true); }
private static void SendChunkToClient(ZRpc client, int chunk) { if (chunk >= CHUNKS) { return; } var size = ExplorationDatabase.MapSizeSquared / CHUNKS; var startIndex = chunk * (ExplorationDatabase.MapSizeSquared / CHUNKS); var z = ExplorationDatabase.PackBoolArray(ExplorationDatabase.GetExplorationArray(), chunk, startIndex, size); if (client == null) { OnReceiveMapDataInitial(null, z); } else { client.Invoke("OnReceiveMapDataInitial", (object)z); } }
private static void RPC_RquestConfigsSellThat(ZRpc rpc) { try { if (!ZNet.instance.IsServer()) { Log.LogWarning("Non-server instance received request for configs. Ignoring request."); } Log.LogInfo("Received request for configs."); ZPackage configPackage = new ZPackage(); var package = new ConfigurationPackage( ConfigurationManager.GeneralConfig, ConfigurationManager.TraderBuyConfig, ConfigurationManager.TraderSellConfig); Log.LogTrace("Serializing configs."); using (MemoryStream memStream = new MemoryStream()) { BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(memStream, package); byte[] serialized = memStream.ToArray(); configPackage.Write(serialized); } Log.LogTrace("Sending config package."); rpc.Invoke(nameof(RPC_ReceiveConfigsSellThat), new object[] { configPackage }); Log.LogTrace("Finished sending config package."); } catch (Exception e) { Log.LogError("Unexpected error while attempting to create and send config package from server to client.", e); } }
/// <summary> /// Store server's message. /// </summary> /// <param name="sender"></param> /// <param name="data"></param> private static void RPC_Jotunn_ReceiveVersionData(ZRpc sender, ZPackage data) { Logger.LogDebug($"Received Version package from {sender.m_socket.GetEndPointString()}"); if (!ZNet.instance.IsClientInstance()) { clientVersions[sender.m_socket.GetEndPointString()] = data; var clientVersion = new ModuleVersionData(clientVersions[sender.GetSocket().GetEndPointString()]); var serverVersion = new ModuleVersionData(GetEnforcableMods().ToList()); if (!clientVersion.Equals(serverVersion)) { // Disconnect if mods are not network compatible sender.Invoke("Error", 3); } } else { lastServerVersion = data; } }
/// <summary> /// Store server's message. /// </summary> /// <param name="sender"></param> /// <param name="data"></param> private static void RPC_Jotunn_ReceiveVersionData(ZRpc sender, ZPackage data) { Logger.LogDebug($"Received Version package from {sender.m_socket.GetEndPointString()}"); if (!ZNet.instance.IsClientInstance()) { ClientVersions[sender.m_socket.GetEndPointString()] = data; var serverData = new ModuleVersionData(GetEnforcableMods().ToList()); var clientData = new ModuleVersionData(data); if (!CompareVersionData(serverData, clientData)) { // Disconnect if mods are not network compatible Logger.LogWarning("RPC_Jotunn_ReceiveVersionData: Disconnecting modded client with incompatible version message. " + "Mods are not compatible"); sender.Invoke("Error", (int)ZNet.ConnectionStatus.ErrorVersion); } } else { LastServerVersion = data; } }
private void Update() { /* * if (AedenthornUtils.CheckKeyDown(openUIKey.Value)) * { * storeOpen = !storeOpen; * * } * return; */ if (ZNet.instance && Player.m_localPlayer && !AedenthornUtils.IgnoreKeyPresses(true) && AedenthornUtils.CheckKeyDown(openUIKey.Value)) { Dbgl("Pressed hotkey"); if (storeOpen) { Dbgl("Closing store"); storeOpen = false; } else { ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (serverRPC != null) { Dbgl("Requesting store data"); JsonCommand command = new JsonCommand() { command = "RequestStoreInfo", id = SteamUser.GetSteamID().ToString() }; string commandJson = JsonUtility.ToJson(command); Dbgl(commandJson); serverRPC.Invoke("SendServerRewardsJSON", new object[] { commandJson }); } } } }
private static IEnumerator SendSettings(ZNet instance, ZRpc rpc, ZPackage pkg) { byte[] ArraySlice(byte[] source, int offset, int length) { var target = new byte[length]; Buffer.BlockCopy(source, offset, target, 0, length); return(target); } var peer = instance.GetPeers().First(p => p.m_rpc == rpc); if (!Settings.EnabledForThisWorld) { Log($"Skipping sending settings to {PeerName(peer)}, as Better Continents is not enabled in this world"); } else { Log($"World is using Better Continents, so client version must match server version {ModInfo.Name}"); if (!ClientInfo.TryGetValue(peer.m_uid, out var bcClientInfo)) { Log($"Client info for {PeerName(peer)} not found, client has an old version of Better Continents, or none!"); rpc.Invoke("Error", ZNet.ConnectionStatus.ErrorConnectFailed); ZNet.instance.Disconnect(peer); yield break; } else if (bcClientInfo.version != ModInfo.Version) { Log($"Client {PeerName(peer)} version {bcClientInfo.version} doesn't match server version {ModInfo.Version}"); peer.m_rpc.Invoke("Error", 69); ZNet.instance.Disconnect(peer); yield break; } else { Log($"Client {PeerName(peer)} version {bcClientInfo.version} matches server version {ModInfo.Version}"); } // This was the initial way that versioning was implemented, before the client->server way, so may // as well leave it in Log($"Sending server version {ModInfo.Version} to client for bi-lateral version agreement"); rpc.Invoke("BetterContinentsVersion", ModInfo.Version); var settingsPackage = new ZPackage(); var cleanSettings = Settings.Clean(); cleanSettings.Serialize(settingsPackage); if (WorldCache.CacheItemExists(settingsPackage, bcClientInfo.worldCache)) { // We send hash and id string cacheId = WorldCache.PackageID(settingsPackage); Log($"Client {PeerName(peer)} already has cached settings for world, instructing it to load those (id {cacheId})"); rpc.Invoke("BetterContinentsConfigLoadFromCache", cacheId); } else { Log($"Client {PeerName(peer)} doesn't have cached settings, sending them now"); cleanSettings.Dump(); var settingsData = settingsPackage.GetArray(); Log($"Sending settings package header for {settingsData.Length} byte stream"); rpc.Invoke("BetterContinentsConfigStart", settingsData.Length, GetHashCode(settingsData)); const int SendChunkSize = 256 * 1024; for (int sentBytes = 0; sentBytes < settingsData.Length;) { int packetSize = Mathf.Min(settingsData.Length - sentBytes, SendChunkSize); var packet = ArraySlice(settingsData, sentBytes, packetSize); rpc.Invoke("BetterContinentsConfigPacket", sentBytes, GetHashCode(packet), new ZPackage(packet)); // Make sure to flush or we will saturate the queue... rpc.GetSocket().Flush(); sentBytes += packetSize; Log($"Sent {sentBytes} of {settingsData.Length} bytes"); float timeout = Time.time + 30; yield return(new WaitUntil(() => rpc.GetSocket().GetSendQueueSize() < SendChunkSize || Time.time > timeout)); if (Time.time > timeout) { Log($"Timed out sending config to client {PeerName(peer)} after 30 seconds, disconnecting them"); peer.m_rpc.Invoke("Error", ZNet.ConnectionStatus.ErrorConnectFailed); ZNet.instance.Disconnect(peer); yield break; } } } yield return(new WaitUntil(() => ClientInfo[peer.m_uid].readyForPeerInfo || !peer.m_socket.IsConnected())); } RPC_PeerInfo(instance, rpc, pkg); }
private static void ZNet_RPC_ServerHandshake(ZNet __instance, ZRpc rpc) { rpc.Invoke(nameof(RPC_Jotunn_ReceiveVersionData), new ModuleVersionData(GetEnforcableMods().ToList()).ToZPackage()); }
private static void RPC_SendJSON(ZRpc rpc, string json) { JsonCommand command = JsonUtility.FromJson <JsonCommand>(json); Dbgl($"RPC_SendJSON received command {command.command} {json} from id {command.id}"); ZNetPeer peer = Traverse.Create(ZNet.instance).Method("GetPeer", new object[] { rpc }).GetValue <ZNetPeer>(); var steamID = (peer.m_socket as ZSteamSocket).GetPeerID(); if (ZNet.instance.IsServer()) { context.UpdatePlayers(true); if (command.command == "BuyPackage") { var inv = GetStoreInventory(); PackageInfo package; try { package = inv.First(p => p.id == command.packageid); } catch { Dbgl($"Package {command.packageid} not found"); return; } PlayerInfo player = GetPlayerInfo(steamID.ToString()); if (player.currency < package.price) { Dbgl($"Player doesn't have enough currency {player.currency}, price {package.price}"); return; } player.currency -= package.price; WritePlayerData(player); JsonCommand sendCommand = new JsonCommand() { command = "PurchaseResult", currency = player.currency, items = GetPackageItems(package, player) }; rpc.Invoke("SendServerRewardsJSON", new object[] { JsonUtility.ToJson(sendCommand) }); } else if (command.command == "RequestStoreInfo") { int currency = GetUserCurrency(steamID.ToString()); if (currency == -1) { Dbgl("Error getting store info"); return; } JsonCommand sendCommand = new JsonCommand() { command = "SendStoreInfo", storeTitle = storeTitle.Value, storeInventory = GetStoreInventoryString(), currencyString = currencyString.Value, currency = currency, }; rpc.Invoke("SendServerRewardsJSON", new object[] { JsonUtility.ToJson(sendCommand) }); } } else { if (command.command == "PurchaseResult") { myCurrency = command.currency; foreach (string itemString in command.items.Split(';')) { Dbgl($"Receving {itemString}"); string[] itemAmount = itemString.Split(','); string name = itemAmount[0]; GameObject prefab = ZNetScene.instance.GetPrefab(name); if (!prefab) { Dbgl($"Item {name} not found!"); continue; } int amount = int.Parse(itemAmount[1]); if (amount == 1) { Instantiate(prefab, Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 2f + Vector3.up, Quaternion.identity); Player.m_localPlayer.Message(MessageHud.MessageType.TopLeft, "Spawning object " + name, 0, null); } else { for (int j = 0; j < amount; j++) { Vector3 b = UnityEngine.Random.insideUnitSphere * 0.5f; Instantiate(prefab, Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 2f + Vector3.up + b, Quaternion.identity); Player.m_localPlayer.Message(MessageHud.MessageType.TopLeft, "Spawning object " + name, 0, null); } } } } else if (command.command == "SendStoreInfo") { if (command.currency == -1) { Dbgl("Error getting store info"); return; } myCurrency = command.currency; windowTitleText = command.storeTitle; currencyString.Value = command.currencyString; storePackages = GetStorePackagesFromString(command.storeInventory); Dbgl($"Got user currency: {myCurrency}"); if (Player.m_localPlayer) { Player.m_localPlayer.Message(MessageHud.MessageType.Center, $"You have {string.Format(command.currencyString, myCurrency)}"); } storeOpen = true; } } }
private static void RPC_SendJSON(ZRpc rpc, string json) { if (!modEnabled.Value) { return; } JsonCommand command = JsonUtility.FromJson <JsonCommand>(json); Dbgl($"RPC_SendJSON received command {command.command} {json} from id {command.id}"); ZNetPeer peer = Traverse.Create(ZNet.instance).Method("GetPeer", new object[] { rpc }).GetValue <ZNetPeer>(); var steamID = (peer.m_socket as ZSteamSocket).GetPeerID(); if (ZNet.instance.IsServer()) { context.UpdatePlayers(true); if (command.command == "BuyPackage") { var packages = GetAllPackages(); PackageInfo package; try { package = packages.First(p => p.id == command.packageid); } catch { Dbgl($"Package {command.packageid} not found"); return; } PlayerInfo player = GetPlayerInfo(steamID.ToString()); if (!CanBuyPackage(ref player, package, true, true, out string result)) { WritePlayerData(player); return; } Dbgl(result); player.currency -= package.price; WritePlayerData(player); JsonCommand sendCommand = new JsonCommand() { command = "PurchaseResult", currency = player.currency, packageid = package.id, packagename = package.name, packagedescription = package.description, items = GetPackageItems(package, player) }; rpc.Invoke("SendServerRewardsJSON", new object[] { JsonUtility.ToJson(sendCommand) }); } else if (command.command == "RequestStoreInfo") { int currency = GetUserCurrency(steamID.ToString()); if (currency == -1) { Dbgl("Error getting store info"); return; } PlayerInfo player = GetPlayerInfo(steamID.ToString()); JsonCommand sendCommand = new JsonCommand() { command = "SendStoreInfo", storeTitle = storeTitleString.Value, storeInventory = GetStoreInventoryString(player), currencyString = currencyString.Value, currency = currency, }; rpc.Invoke("SendServerRewardsJSON", new object[] { JsonUtility.ToJson(sendCommand) }); } } else { if (command.command == "PurchaseResult") { Traverse.Create(GameCamera.instance).Field("m_mouseCapture").SetValue(true); Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; storeOpen = false; //PlayEffects(); var items = command.items.Split(';'); GameObject chest = null; PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); Traverse inventoryT = null; if (useTombstone.Value) { chest = Instantiate(Player.m_localPlayer.m_tombstone, Player.m_localPlayer.GetCenterPoint() + Player.m_localPlayer.transform.forward, Player.m_localPlayer.transform.rotation); chest.GetComponent <Container>().m_name = command.packagename; inventoryT = Traverse.Create(chest.GetComponent <Container>().GetInventory()); inventoryT.Field("m_name").SetValue(command.packagename); inventoryT.Field("m_width").SetValue(8); int rows = items.Count() / 8 + 2; if (items.Count() % 8 != 0) { rows++; } inventoryT.Field("m_height").SetValue(rows); TombStone tombstone = chest.GetComponent <TombStone>(); tombstone.Setup(command.packagename, playerProfile.GetPlayerID()); } myCurrency = command.currency; List <string> itemStrings = new List <string>(); foreach (string itemString in items) { Dbgl($"Receving {itemString}"); string[] nameAmount = itemString.Split(','); string name = nameAmount[0]; GameObject prefab = ZNetScene.instance.GetPrefab(name); if (!prefab) { Dbgl($"Item {name} not found!"); continue; } int amount = int.Parse(nameAmount[1]); if (useTombstone.Value) { ItemDrop.ItemData item = prefab.GetComponent <ItemDrop>().m_itemData; double slotsNeed = amount / item.m_shared.m_maxStackSize / 8; inventoryT.Field("m_height").SetValue((int)inventoryT.Field("m_height").GetValue() + (int)Math.Round(slotsNeed, 0)); while (amount >= item.m_shared.m_maxStackSize) { int stack = Mathf.Min(item.m_shared.m_maxStackSize, amount); //chest.GetComponent<Container>().GetInventory().AddItem(_newItem); chest.GetComponent <Container>().GetInventory().AddItem(name, stack, item.m_quality, item.m_variant, Player.m_localPlayer.GetPlayerID(), Player.m_localPlayer.GetPlayerName()); amount = amount - stack; } if (amount > 0) { //chest.GetComponent<Container>().GetInventory().AddItem(_newItem2); chest.GetComponent <Container>().GetInventory().AddItem(name, amount, item.m_quality, item.m_variant, Player.m_localPlayer.GetPlayerID(), Player.m_localPlayer.GetPlayerName()); } itemStrings.Add($"{Localization.instance.Localize(item.m_shared.m_name)} {nameAmount[0]}"); } else { if (amount == 1) { var go = Instantiate(prefab, Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 2f + Vector3.up, Quaternion.identity); var item = go.GetComponent <ItemDrop>().m_itemData; item.m_durability = item.m_shared.m_maxDurability; Player.m_localPlayer.Message(MessageHud.MessageType.TopLeft, string.Format(rewardString.Value, Localization.instance.Localize(go.GetComponent <ItemDrop>().m_itemData.m_shared.m_name)), 0, null); } else { for (int j = 0; j < amount; j++) { Vector3 b = UnityEngine.Random.insideUnitSphere * 0.5f; var go = Instantiate(prefab, Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 2f + Vector3.up + b, Quaternion.identity); var item = go.GetComponent <ItemDrop>().m_itemData; item.m_durability = item.m_shared.m_maxDurability; Player.m_localPlayer.Message(MessageHud.MessageType.TopLeft, Localization.instance.Localize(go.GetComponent <ItemDrop>().m_itemData.m_shared.m_name), 0, null); } } } } if (useTombstone.Value) { inventoryT.Method("Changed").GetValue(); chest.GetComponent <ZNetView>().GetZDO().Set("ServerReward", string.Format(packageInfoString.Value, command.packagename, playerProfile.GetName()) + "\r\n" + string.Join("\r\n", itemStrings)); } } else if (command.command == "SendStoreInfo") { if (command.currency == -1) { Dbgl("Error getting store info"); return; } myCurrency = command.currency; windowTitleText = command.storeTitle; currencyString.Value = command.currencyString; storePackages = GetStorePackagesFromString(command.storeInventory); Dbgl($"Got store inventory {storePackages.Count}, user currency: {myCurrency}"); storeOpen = true; } else if (command.command == "SendConsoleString") { Traverse.Create(Console.instance).Method("AddString", new object[] { command.data }).GetValue(); Dbgl(command.data); } } }
// Send server module list to client private static void ZNet_RPC_ServerHandshake(On.ZNet.orig_RPC_ServerHandshake orig, ZNet self, ZRpc rpc) { rpc.Invoke(nameof(RPC_Jotunn_ReceiveVersionData), new ModuleVersionData(GetEnforcableMods().ToList()).ToZPackage()); orig(self, rpc); }
private void WindowBuilder(int id) { GUI.DragWindow(new Rect(0, 0, windowWidth.Value, 20)); GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(windowWidth.Value) }); GUILayout.Label(windowTitleText, titleStyle); GUILayout.BeginHorizontal(); GUILayout.Label(myCurrencyString.Value, currencyStyle); if (coinBeforeAmount.Value) { GUILayout.Space(5); GUILayout.Button(textureDict["currency"], coinStyle, new GUILayoutOption[] { GUILayout.Width(currencyFontSize.Value * coinFactor), GUILayout.Height(currencyFontSize.Value) }); } GUILayout.Space(5); GUILayout.Label(string.Format(currencyString.Value, myCurrency), currencyStyle); if (!coinBeforeAmount.Value) { GUILayout.Space(5); GUILayout.Button(textureDict["currency"], coinStyle, new GUILayoutOption[] { GUILayout.Width(currencyFontSize.Value * coinFactor), GUILayout.Height(currencyFontSize.Value) }); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); float width = windowWidth.Value - 70; float itemWidth = width / packagesPerRow.Value; scrollPosition = GUILayout.BeginScrollView(scrollPosition, new GUILayoutOption[] { GUILayout.Width(windowWidth.Value - 20) }); GUILayout.Space(10); GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(width) }); GUILayout.BeginHorizontal(); storePackages.Sort(delegate(PackageInfo a, PackageInfo b) { return(a.price.CompareTo(b.price)); }); for (int i = 0; i < storePackages.Count; i++) { if (i > 0 && i % packagesPerRow.Value == 0) { GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.BeginHorizontal(); } PackageInfo pi = storePackages[i]; string texture = textureDict.ContainsKey(pi.type) ? pi.type : "Common"; GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(itemWidth) }); if (GUILayout.Button(new GUIContent(textureDict[texture], "This is a test"), new GUILayoutOption[] { GUILayout.Width(itemWidth), GUILayout.Height(itemWidth) })) { if (myCurrency >= pi.price) { if (testing.Value) { myCurrency -= pi.price; storeOpen = false; PlayEffects(); } else { ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (serverRPC != null) { Dbgl("Requesting store data"); JsonCommand command = new JsonCommand() { command = "BuyPackage", packageid = pi.id }; string commandJson = JsonUtility.ToJson(command); Dbgl(commandJson); serverRPC.Invoke("SendServerRewardsJSON", new object[] { commandJson }); } } } } if (GUI.tooltip != null && GUI.tooltip.Length > 0) { thisTooltip = GUI.tooltip; } GUILayout.Label(string.Format(packageString.Value, pi.name), labelStyle, new GUILayoutOption[] { GUILayout.Width(itemWidth) }); GUILayout.BeginHorizontal(new GUILayoutOption[] { GUILayout.Width(itemWidth) }); GUILayout.FlexibleSpace(); if (coinBeforeAmount.Value) { GUILayout.Button(textureDict["currency"], coinStyle, new GUILayoutOption[] { GUILayout.Width(labelFontSize.Value * coinFactor), GUILayout.Height(labelFontSize.Value) }); GUILayout.Space(5); } GUILayout.Label(string.Format(currencyString.Value, pi.price), labelStyle); if (!coinBeforeAmount.Value) { GUILayout.Space(5); GUILayout.Button(textureDict["currency"], coinStyle, new GUILayoutOption[] { GUILayout.Width(labelFontSize.Value * coinFactor), GUILayout.Height(labelFontSize.Value) }); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); }
//CALLED ON SERVER, Should contain ZDOID and Inventory public static void RPC_CharacterIDX(ZRpc rpc, ZPackage pkg) { ZDOID characterID = pkg.ReadZDOID(); ZNetPeer peer = (ZNetPeer)_GetPeerMethod.Invoke(ZNet.instance, new object[] { rpc }); if (peer != null) { peer.m_characterID = characterID; if (Configs.ShowDebugMessages.Value) { ZLog.Log($"Got character ZDOID with inventory from {peer.m_playerName} : {characterID}!"); } } ZPackage inventoryPackage = pkg.ReadPackage(); String characterName = inventoryPackage.ReadString(); int itemsCount = inventoryPackage.ReadInt(); String steamId = rpc.GetSocket().GetEndPointString(); if (Configs.ShowDebugMessages.Value) { Instance.Logger.LogInfo($"Getting player {characterName}'s ({steamId}) inventory..."); } List <Server_ItemData> playerItems = new List <Server_ItemData>(); for (int i = 0; i < itemsCount; i++) { Server_ItemData data = new Server_ItemData { Name = inventoryPackage.ReadString(), Stack = inventoryPackage.ReadInt(), Quality = inventoryPackage.ReadInt(), Variant = inventoryPackage.ReadInt() }; playerItems.Add(data); } if (Configs.ShowDebugMessages.Value) { Instance.Logger.LogInfo($"Found {playerItems.Count} items in {characterName}'s inventory."); } String dbId = $"{steamId}_{characterName}"; var dbPlayer = Instance.DB.GetPlayerById(dbId); if (dbPlayer == null) { if (Configs.ShowDebugMessages.Value) { Instance.Logger.LogInfo($"{characterName} is a new character!"); } DBClasses.DBPlayer[] characters = Instance.DB.GetPlayersBySteamId(steamId); if (characters.Length >= Configs.MaxCharactersPerPlayer.Value) { rpc.Invoke("Error", new object[] { (int)ZNet.ConnectionStatus.ErrorVersion }); return; } dbPlayer = new DBClasses.DBPlayer() { DBPlayerId = dbId, SteamId = steamId, CharacterName = characterName, Items = new List <DBClasses.DBItem>() }; foreach (var item in playerItems) { dbPlayer.Items.Add(new DBClasses.DBItem() { ItemName = item.Name, PlayerId = dbPlayer.DBPlayerId, StackCount = item.Stack, Quality = item.Quality, Variant = item.Variant }); } Instance.DB.InsertPlayer(dbPlayer); } else { bool isSame = true; if (dbPlayer.Items.Count != playerItems.Count) { isSame = false; } else { for (int i = 0; i < dbPlayer.Items.Count; i++) { if (dbPlayer.Items[i].ItemName != playerItems[i].Name || dbPlayer.Items[i].StackCount != playerItems[i].Stack || dbPlayer.Items[i].Quality != playerItems[i].Quality || dbPlayer.Items[i].Variant != playerItems[i].Variant) { isSame = false; break; } } } if (isSame) { if (Configs.ShowDebugMessages.Value) { Instance.Logger.LogInfo($"{characterName} is still the same"); } dbPlayer.LastLoggedIn = DateTime.Now; Instance.DB.UpdatePlayer(dbPlayer); } else { if (Configs.ShowDebugMessages.Value) { Instance.Logger.LogWarning($"{characterName} is NOT the same!"); } rpc.Invoke("Error", new object[] { (int)ZNet.ConnectionStatus.ErrorVersion }); } } }
private static void RPC_ConsoleCommand(ZRpc rpc, string command) { if (!modEnabled.Value || !ZNet.instance.IsServer()) { return; } ZNetPeer peer = Traverse.Create(ZNet.instance).Method("GetPeer", new object[] { rpc }).GetValue <ZNetPeer>(); var steamID = (peer.m_socket as ZSteamSocket).GetPeerID(); Dbgl($"RPC_ConsoleCommand received command {command} from {steamID}"); if (!Traverse.Create(ZNet.instance).Field("m_adminList").GetValue <SyncedList>().Contains(rpc.GetSocket().GetHostName())) { Dbgl("User is not admin!"); return; } var parts = command.Split(' ').Skip(1).ToArray(); string result = ""; if (parts[0] == "help") { result = "Usage:\r\n" + "serverrewards list users\r\n" + "serverrewards list packages\r\n" + "serverrewards give <steamID> <currency>\r\n" + "serverrewards give all <currency>\r\n" + "serverrewards set <steamID> <currency>\r\n" + "serverrewards set all <currency>\r\n" + "serverrewards givepackage <steamID> <packageID>\r\n" + "serverrewards givepackage all <packageID>\r\n" + "serverrewards spawn <spawnName>"; } else if (parts[0] == "list" && parts.Length == 2) { if (parts[1] == "users") { List <string> userList = new List <string>(); List <string> users = GetAllPlayerIDs(); var peerList = ZNet.instance.GetConnectedPeers(); foreach (string user in users) { string online = "(offline)"; var tp = peerList.Find(p => (p.m_socket as ZSteamSocket).GetPeerID().ToString() == user); if (tp != null) { online = tp.m_playerName + " (online)"; } userList.Add(user + " " + online); } result = string.Join("\r\n", userList); } else if (parts[1] == "packages") { List <string> packageList = new List <string>(); var packages = GetAllPackages(); foreach (PackageInfo p in packages) { packageList.Add(p.id + " " + p.price); } result = string.Join("\r\n", packageList); } else { result = "Syntax error."; } } else if (parts[0] == "give" && parts.Length == 3) { try { string id = GetSteamID(parts[1]); if (id == null) { result = "User not found."; } else if (AdjustCurrency(id, int.Parse(parts[2]))) { result = "Balance adjusted."; } else { result = "Error adjusting player balance."; } } catch { result = "Syntax error."; } } else if (parts[0] == "set" && parts.Length == 3) { try { string id = GetSteamID(parts[1]); if (id == null) { result = "User not found."; } else if (SetCurrency(id, int.Parse(parts[2]))) { result = "Balance set."; } else { result = "Error setting player balance."; } } catch { result = "Syntax error."; } } else if (parts[0] == "givepackage" && parts.Length == 3) { if (parts[1] == "all") { IEnumerable <string> users = GetAllPlayerIDs(); int count = 0; foreach (string user in users) { string r = GivePackage(parts[1], parts[2]); if (r == null) { count++; } } result = $"Package sent to {count} users!"; } else { string id = GetSteamID(parts[1]); if (id == null) { result = "User not found."; } else { result = GivePackage(id, parts[2]); if (result == null) { result = "Package sent!"; } } } } else if (parts[0] == "spawn" && parts.Length == 2) { GameObject prefab = ZNetScene.instance.GetPrefab(parts[1]); if (!prefab) { result = $"Item {parts[1]} not found!"; } else { var go = Instantiate(prefab, Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 2f + Vector3.up, Quaternion.identity); Player.m_localPlayer.Message(MessageHud.MessageType.TopLeft, string.Format(packageInfoString.Value, Localization.instance.Localize(go.GetComponent <ItemDrop>().m_itemData.m_shared.m_name)), 0, null); } } else { result = "Syntax error."; } JsonCommand sendCommand = new JsonCommand() { command = "SendConsoleString", data = result }; rpc.Invoke("SendServerRewardsJSON", new object[] { JsonUtility.ToJson(sendCommand) }); Dbgl(result); }