static void NotifyOtherPlayersOfDeath(ZRoutedRpc __instance, ZRoutedRpc.RoutedRPCData rpcData) { // Late bind to instance if (_getPeer == null) { _getPeer = (Func <long, ZNetPeer>)Delegate.CreateDelegate(typeof(Func <long, ZNetPeer>), __instance, _getPeerInfo); } if (ZNet.instance == null || !ZNet.instance.IsServer()) { return; } if (rpcData.m_methodHash != _onDeathHash) { return; } ZNetPeer peer = _getPeer(rpcData.m_senderPeerID); if (peer == null) { return; } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ShowMessage", 2, "Player " + peer.m_playerName + " has died."); }
public static void Postfix(ref ZRoutedRpc __instance, ref ZNetPeer peer) { // Send a greeting message to the server or client. if (ZNet.m_isServer) { GreetingMessage.SendToClient(peer.m_uid); } else { GreetingMessage.SendToServer(); } }
public static void RegisterRPC(ZRoutedRpc routedRpc) { if (!Common.Utils.IsServer()) { routedRpc.Register <ZPackage>(Name_RPC_ServerKnownMats, RPC_ServerKnownMats); routedRpc.Register <ZPackage>(Name_RPC_ServerKnownRecipes, RPC_ServerKnownRecipes); } routedRpc.Register <ZPackage>(Name_RPC_ClientKnownMats, RPC_ClientKnownMats); routedRpc.Register <ZPackage>(Name_RPC_ClientKnownRecipes, RPC_ClientKnownRecipes); routedRpc.Register <string>(Name_RPC_AddKnownRecipe, RPC_AddKnownRecipe); routedRpc.Register <string>(Name_RPC_AddKnownMaterial, RPC_AddKnownMaterial); }
public static void RegisterNewNetRPCs(ZRoutedRpc zrpc) { Utils.Log($"Registering server side and client side RPCs for Map Sharing Made Easy"); if (zrpc == null) { Utils.Log("No zrpc instance found"); return; } zrpc.Register("SetMapSharingConfigValues", new Action <long, ZPackage>(RPC_ClientSetConfigValues)); zrpc.Register("CheckMapSharingModVersion", new Action <long, ZPackage>(RPC_ClientCheckModVersion)); zrpc.Register("ReceiveMapData", new Action <long, ZPackage>(MapTransfer.RPC_ReceiveMapData)); }
public static bool Prefix(ref ZRoutedRpc __instance, ref RoutedRPCData data) { if (ZNet.m_isServer && data?.m_methodHash == GlobalMessages.TalkerSayHashCode) { // Read local say chat messages for users not connected to VChat. // Messages that fit the global chat command name will be redirected as global chat messages. if (GreetingMessage.PeerInfo.TryGetValue(data.m_senderPeerID, out GreetingMessagePeerInfo peerInfo) && !peerInfo.HasReceivedGreeting) { try { var senderPeer = ZNet.instance.GetPeer(data.m_senderPeerID); var package = new ZPackage(data.m_parameters.GetArray()); var ctype = package.ReadInt(); var playerName = package.ReadString(); var text = package.ReadString(); if (ctype == (int)Talker.Type.Normal) { var globalChatCommand = VChatPlugin.CommandHandler.FindCommand(PluginCommandType.SendGlobalMessage); if (VChatPlugin.CommandHandler.IsValidCommandString(text, globalChatCommand, out text)) { VChatPlugin.Log($"Redirecting local message to global chat from peer {data.m_senderPeerID} \"({senderPeer?.m_playerName})\" with message \"{text}\"."); // Redirect this message to the global chat channel. foreach (var peer in ZNet.instance.GetConnectedPeers()) { // Exclude the sender, otherwise it'd probably just be annoying. if (peer.m_uid != data.m_senderPeerID) { GlobalMessages.SendGlobalMessageToPeer(peer.m_uid, (int)GlobalMessageType.RedirectedGlobalMessage, senderPeer?.m_refPos ?? new Vector3(), senderPeer?.m_playerName ?? playerName, text); } } // Intercept message so that other connected users won't receive the same message twice. data.m_methodHash = GlobalMessages.InterceptedSayHashCode; return(false); } } } catch (Exception ex) { VChatPlugin.LogError($"Error reading Talker.Say message for unconnected VChat user ({data.m_senderPeerID}): {ex}"); } } } return(true); }
public void RegisterRPC(ZRoutedRpc routedRpc) { //routedRpc.Register<ZPackage>("SpawnBounties", RPC_SpawnBounties); routedRpc.Register <string>("SendKillLogs", RPC_Client_ReceiveKillLogs); if (Common.Utils.IsServer()) { routedRpc.Register <ZPackage, string, bool>("SlayBountyTarget", RPC_SlayBountyTarget); routedRpc.Register <long>("RequestKillLogs", RPC_Server_RequestKillLogs); routedRpc.Register <long>("ClearKillLogs", RPC_Server_ClearKillLogs); } else { routedRpc.Register <ZPackage, string, bool>("SlayBountyTargetFromServer", RPC_Client_SlayBountyTargetFromServer); } }
public static bool Prefix(ref ZRoutedRpc __instance, ref ZRoutedRpc.RoutedRPCData rpcData) { if (VPlusChatFilter.isEnabled.Value) { if (rpcData.m_methodHash == "ChatMessage".GetStableHashCode()) { ZPackage payload = rpcData.m_parameters; VPlusChatFilter.chatFilterLogger.LogDebug("ChatMessage Sent"); payload.SetPos(0); VPlusChatFilter.chatFilterLogger.LogDebug("Size of package is " + payload.Size()); VPlusChatFilter.chatFilterLogger.LogDebug("Read byte test : " + payload.ReadInt()); payload.SetPos(0); Vector3 headPoint = payload.ReadVector3(); VPlusChatFilter.chatFilterLogger.LogDebug("Read head : " + headPoint.ToString()); int messageType = payload.ReadInt(); VPlusChatFilter.chatFilterLogger.LogDebug("Read type : " + messageType); string playerName = payload.ReadString(); VPlusChatFilter.chatFilterLogger.LogDebug("Read name : " + playerName); string message = payload.ReadString(); VPlusChatFilter.chatFilterLogger.LogDebug("Read message : " + message); var profanities = FamilyFriendlyfier.filter.DetectAllProfanities(message, true); if (profanities.Count > 0) { foreach (string bannable in profanities) { VPlusChatFilter.chatFilterLogger.LogInfo("Bad word from " + playerName + " : " + bannable); } message = FamilyFriendlyfier.filter.CensorString(message, VPlusChatFilter.replaceKey.Value[0]); } VPlusChatFilter.chatFilterLogger.LogDebug("New message : " + message); ZPackage newpayload = new ZPackage(); ZRpc.Serialize(new object[] { headPoint, messageType, playerName, message }, ref newpayload); rpcData.m_parameters = newpayload; } else if (rpcData.m_methodHash == "Say".GetStableHashCode()) { ZPackage payload = rpcData.m_parameters; VPlusChatFilter.chatFilterLogger.LogDebug("Say Sent"); payload.SetPos(0); VPlusChatFilter.chatFilterLogger.LogDebug("Size of package is " + payload.Size()); VPlusChatFilter.chatFilterLogger.LogDebug("Read byte test : " + payload.ReadInt()); payload.SetPos(0); int messageType = payload.ReadInt(); VPlusChatFilter.chatFilterLogger.LogDebug("Read type : " + messageType); string playerName = payload.ReadString(); VPlusChatFilter.chatFilterLogger.LogDebug("Read name : " + playerName); string message = payload.ReadString(); VPlusChatFilter.chatFilterLogger.LogDebug("Read message : " + message); var profanities = FamilyFriendlyfier.filter.DetectAllProfanities(message, true); if (profanities.Count > 0) { foreach (string bannable in profanities) { VPlusChatFilter.chatFilterLogger.LogInfo("Bad word from " + playerName + " : " + bannable); } message = FamilyFriendlyfier.filter.CensorString(message, VPlusChatFilter.replaceKey.Value[0]); } VPlusChatFilter.chatFilterLogger.LogDebug("New message : " + message); ZPackage newpayload = new ZPackage(); ZRpc.Serialize(new object[] { messageType, playerName, message }, ref newpayload); rpcData.m_parameters = newpayload; } ZPackage zpackage = new ZPackage(); rpcData.Serialize(zpackage); if (__instance.m_server) { if (rpcData.m_targetPeerID != 0L) { ZNetPeer peer = __instance.GetPeer(rpcData.m_targetPeerID); if (peer != null && peer.IsReady()) { peer.m_rpc.Invoke("RoutedRPC", new object[] { zpackage }); return(false); } return(false); } else { using (List <ZNetPeer> .Enumerator enumerator = __instance.m_peers.GetEnumerator()) { while (enumerator.MoveNext()) { ZNetPeer znetPeer = enumerator.Current; if (rpcData.m_senderPeerID != znetPeer.m_uid && znetPeer.IsReady()) { znetPeer.m_rpc.Invoke("RoutedRPC", new object[] { zpackage }); } } return(false); } } } foreach (ZNetPeer znetPeer2 in __instance.m_peers) { if (znetPeer2.IsReady()) { znetPeer2.m_rpc.Invoke("RoutedRPC", new object[] { zpackage }); } } } return(true); }
internal static void ZRoutedRpc_Register(On.ZRoutedRpc.orig_Register orig, ZRoutedRpc self, string name, Action <long> f) { Debug.Log("Registered RPC: " + name + " (" + name.GetStableHashCode() + ")"); orig(self, name, f); }
/// <summary> /// Coroutine to send a package to an actual peer. /// </summary> /// <param name="peer"></param> /// <param name="package"></param> /// <returns></returns> private IEnumerator <bool> SendToPeer(ZNetPeer peer, ZPackage package) { ZRoutedRpc rpc = ZRoutedRpc.instance; if (rpc == null) { yield break; } const int packageSliceSize = 250000; const int maximumSendQueueSize = 20000; IEnumerable <bool> WaitForQueue() { float timeout = Time.time + 30; while (peer.m_socket.GetSendQueueSize() > maximumSendQueueSize) { if (Time.time > timeout) { Logger.LogInfo($"Disconnecting {peer.m_uid} after 30 seconds sending timeout"); peer.m_rpc.Invoke("Error", ZNet.ConnectionStatus.ErrorConnectFailed); ZNet.instance.Disconnect(peer); yield break; } yield return(false); } } void Send(ZPackage pkg) { rpc.InvokeRoutedRPC(peer.m_uid, ID, pkg); } if (package.Size() > packageSliceSize) { byte[] data = package.GetArray(); int fragments = (int)(1 + (data.LongLength - 1) / packageSliceSize); long packageIdentifier = ++PackageCount; for (int fragment = 0; fragment < fragments; fragment++) { foreach (bool wait in WaitForQueue()) { yield return(wait); } if (!peer.m_socket.IsConnected()) { yield break; } ZPackage fragmentedPackage = new ZPackage(); fragmentedPackage.Write(FRAGMENTED_PACKAGE); fragmentedPackage.Write(packageIdentifier); fragmentedPackage.Write(fragment); fragmentedPackage.Write(fragments); fragmentedPackage.Write(data.Skip(packageSliceSize * fragment).Take(packageSliceSize).ToArray()); Logger.LogDebug($"[{ID}] Sending fragmented package {packageIdentifier}:{fragment}"); Send(fragmentedPackage); if (fragment != fragments - 1) { yield return(true); } } } else { foreach (bool wait in WaitForQueue()) { yield return(wait); } Logger.LogDebug($"[{ID}] Sending package"); Send(package); } }