예제 #1
0
 /// <summary>
 /// Triggered when the server receives a global message from a client .
 /// </summary>
 /// <remarks>Player name and position are primarily here for future work, player aliases for example.</remarks>
 /// <param name="senderId">The peer id of the sender</param>
 /// <param name="pos">The reported position</param>
 /// <param name="type">Reserved for future use</param>
 /// <param name="callerName">The reported player name</param>
 /// <param name="text">the message, without a playername or formatting.</param>
 private static void OnGlobalMessage_Server(long senderId, Vector3 pos, int type, string callerName, string text)
 {
     if (senderId != ZNet.instance.GetServerPeer()?.m_uid)
     {
         var globalMessageType = (GlobalMessageType)type;
         if (globalMessageType == GlobalMessageType.StandardMessage || globalMessageType == GlobalMessageType.RedirectedGlobalMessage)
         {
             try
             {
                 // Sender should always be found but who knows what can happen within a few milliseconds, though I bet its still cached should that player disconnect.. safety first.
                 // We simply apply the position and player name the server knows rather than the reported values first.
                 var peer = ZRoutedRpc.instance?.GetPeer(senderId);
                 if (peer?.m_server == false)
                 {
                     // Loop through every connected peer and redirect the received message, including the original sender because the code is currently set so that the client knows that it's been sent.
                     foreach (var connectedPeer in ZNet.instance.GetConnectedPeers())
                     {
                         if (connectedPeer != null && !connectedPeer.m_server && connectedPeer.IsReady() && connectedPeer.m_socket?.IsConnected() == true)
                         {
                             VChatPlugin.Log($"Routing global message to peer {connectedPeer.m_uid} \"({connectedPeer.m_playerName})\" with message \"{text}\".");
                             SendGlobalMessageToPeer(connectedPeer.m_uid, type, peer?.m_refPos ?? pos, peer?.m_playerName ?? callerName, text);
                         }
                     }
                 }
                 else
                 {
                     VChatPlugin.LogWarning($"Received a global chat message from a peer identified as a server, id {senderId} \"{peer.m_playerName}\"");
                 }
             }
             catch (Exception ex)
             {
                 VChatPlugin.LogError($"Failed to InvokeRoutedRPC for global message ({senderId}|{text}): {ex}");
             }
         }
         else
         {
             VChatPlugin.LogWarning($"A global message type with value of {type} could not be parsed. Please check if there are any updates available.");
         }
     }
     else
     {
         VChatPlugin.LogWarning($"Received a greeting from a peer with the server id...");
     }
 }
예제 #2
0
 /// <summary>
 /// Triggered when the client receives a global message from the server.
 /// </summary>
 /// <remarks>Player name and position are primarily here for future work, player aliases for example.</remarks>
 /// <param name="senderId">The peer id of the sender</param>
 /// <param name="pos">The position</param>
 /// <param name="type">Reserved for future use</param>
 /// <param name="playerName">The player name</param>
 /// <param name="text">the message, without a playername or formatting.</param>
 private static void OnGlobalMessage_Client(long senderId, Vector3 pos, int type, string playerName, string text)
 {
     // If the client is connected to a server-sided instance of VChat then only accept messages from the server.
     if (!GreetingMessage.HasLocalPlayerReceivedGreetingFromServer || senderId == ZNet.instance.GetServerPeer()?.m_uid)
     {
         VChatPlugin.Log($"Received a global message from {playerName} ({senderId}) on location {pos} with message \"{text}\".");
         if (Chat.instance != null)
         {
             var formattedMessage = VChatPlugin.GetFormattedMessage(new CombinedMessageType(CustomMessageType.Global), playerName, text);
             Chat.instance?.AddString(formattedMessage);
         }
         else
         {
             VChatPlugin.LogWarning($"Received a message but Chat instance is undefined.");
         }
     }
     else
     {
         VChatPlugin.LogWarning($"Ignoring a global message received from a client, reported values: {senderId} \"{playerName}\" on location {pos} with message \"{text}\".");
     }
 }
예제 #3
0
        /// <summary>
        /// Get the latest github release tag name from a repository.
        /// </summary>
        /// <param name="author">The owner of the repository</param>
        /// <param name="repositoryName">The repository name</param>
        /// <param name="isPrerelease">Returns if the found release is a pre-release</param>
        /// <param name="includePrerelease">Whether or not prereleases should be returned</param>
        /// <returns>The tag name of the release</returns>
        public static string GetLatestGithubRelease(string author, string repositoryName, out bool isPrerelease, bool includePrerelease = false)
        {
            isPrerelease = false;
            try
            {
                var webClient = new WebClient();
                webClient.Headers.Add("User-Agent: VChat-version-checker");
                var jsonString = webClient.DownloadString($"{GithubApiBaseUri}/repos/{author}/{repositoryName}/releases");

                // Bit hacky but this way I won't have to include a json library.
                while (true)
                {
                    int pos = 0;

                    // Get the version name, aka the tag.
                    var tagName = jsonString.Between("\"tag_name\":\"", "\"", out pos, pos);
                    if (string.IsNullOrEmpty(tagName))
                    {
                        return(null);
                    }

                    // See if this is a prerelease.
                    var isPrereleaseString = jsonString.Between("\"prerelease\":", ",", out pos, pos);
                    bool.TryParse(isPrereleaseString, out isPrerelease);
                    if (includePrerelease || !isPrerelease)
                    {
                        return(tagName);
                    }

                    jsonString = new string(jsonString.Skip(pos).ToArray());
                }
            }
            catch (Exception ex)
            {
                VChatPlugin.LogWarning($"Unable to find the github release for {author}/{repositoryName}: {ex}");
            }

            return(null);
        }
예제 #4
0
        /// <summary>
        /// When the server receives a greeting from the client.
        /// This makes us aware that the user has VChat installed.
        /// </summary>
        private static void OnServerMessage(long senderId, string version)
        {
            if (senderId != ZNet.instance.GetServerPeer()?.m_uid)
            {
                var peer = ZRoutedRpc.instance?.GetPeer(senderId);
                if (peer != null)
                {
                    VChatPlugin.Log($"Greeting received from client \"{peer?.m_playerName}\" ({senderId}) with version {version}.");
                    GreetingMessagePeerInfo peerInfo;
                    if (PeerInfo.TryGetValue(senderId, out GreetingMessagePeerInfo previousGreeting))
                    {
                        peerInfo                     = previousGreeting;
                        peerInfo.Version             = version;
                        peerInfo.HasReceivedGreeting = true;
                    }
                    else
                    {
                        peerInfo = new GreetingMessagePeerInfo()
                        {
                            PeerId              = senderId,
                            Version             = version,
                            HasReceivedGreeting = true,
                            HasSentGreeting     = false,
                        };
                    }

                    PeerInfo.AddOrUpdate(senderId, peerInfo, (long oldKey, GreetingMessagePeerInfo oldValue) => peerInfo);
                }
                else
                {
                    VChatPlugin.LogWarning($"Received greeting from an unconnected peer with id {senderId}.");
                }
            }
            else
            {
                VChatPlugin.LogWarning($"Received a greeting from a peer with the server id...");
            }
        }
예제 #5
0
        /// <summary>
        /// Send a VChat greeting message to a client, this should only be called on a server.
        /// </summary>
        public static void SendToClient(long peerId)
        {
            if (ZNet.m_isServer)
            {
                var parameters = new object[] { VChatPlugin.Version };
                ZRoutedRpc.instance.InvokeRoutedRPC(peerId, GreetingHashName, parameters);

                // Add or update peer info
                GreetingMessagePeerInfo peerInfo;
                if (PeerInfo.TryGetValue(peerId, out GreetingMessagePeerInfo previousGreeting))
                {
                    if (previousGreeting.HasSentGreeting)
                    {
                        VChatPlugin.LogWarning($"Player \"{ZNet.instance.GetPeer(peerId)?.m_playerName}\" ({peerId}) has already been greeted, but sending anyway.");
                    }

                    peerInfo = previousGreeting;
                    peerInfo.HasSentGreeting = true;
                }
                else
                {
                    peerInfo = new GreetingMessagePeerInfo()
                    {
                        PeerId              = peerId,
                        Version             = null,
                        HasReceivedGreeting = false,
                        HasSentGreeting     = true,
                    };
                }

                PeerInfo.AddOrUpdate(peerId, peerInfo, (long oldKey, GreetingMessagePeerInfo oldValue) => peerInfo);
            }
            else
            {
                VChatPlugin.LogWarning($"Cannot send the greeing to a client.");
            }
        }