public override void OnMessageReceived(ClientObject client, ClientMessage message)
        {
            if (!client.authenticated)
            {
                //Only handle authenticated messages
                return;
            }

            if (message.type == ClientMessageType.SCENARIO_DATA)
            {
                HandleScenarioMessage(client, message);
                message.handled = true;
            }
        }
Exemple #2
0
 public void OnMessageReceived(ClientObject client, ClientMessage message)
 {
     if (message.type == ClientMessageType.CHAT_MESSAGE)
     {
         using (MessageReader mr = new MessageReader(message.data, false))
         {
             ChatMessageType messageType = (ChatMessageType)mr.Read<int>();
             string fromPlayer = mr.Read<string>();
             if (messageType == ChatMessageType.CHANNEL_MESSAGE)
             {
                 string channel = mr.Read<string>();
                 string umessage = mr.Read<string>();
                 ircClient.Channels["#" + channel].SendMessage(String.Format("{0} -> {1}", fromPlayer, umessage));
             }
         }
     }
 }
        //Fire OnMessageReceived
        public static void FireOnMessageReceived(ClientObject client, ClientMessage message)
        {
            bool handledByAny = false;
            foreach (var plugin in loadedPlugins)
            {
                try
                {
                    plugin.OnMessageReceived(client, message);

                    //prevent plugins from unhandling other plugin's handled requests
                    if (message.handled)
                    {
                        handledByAny = true;
                    }
                }
                catch (Exception e)
                {
                    Type type = plugin.GetType();
                    DarkLog.Debug("Error thrown in OnMessageReceived event for " + type.FullName + " (" + type.Assembly.FullName + "), Exception: " + e);
                }
            }
            message.handled = handledByAny;
        }
 //Called from warpWorker
 public void SendWarpMessage(byte[] messageData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.WARP_CONTROL;
     newMessage.data = messageData;
     QueueOutgoingMessage(newMessage, true);
 }
 //Called from vesselWorker
 public void SendVesselRemove(string vesselID, bool isDockingUpdate)
 {
     DarkLog.Debug("Removing " + vesselID + " from the server");
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.VESSEL_REMOVE;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<int>(TimeSyncer.fetch.currentSubspace);
         mw.Write<double>(Planetarium.GetUniversalTime());
         mw.Write<string>(vesselID);
         mw.Write<bool>(isDockingUpdate);
         if (isDockingUpdate)
         {
             mw.Write<string>(Settings.fetch.playerName);
         }
         newMessage.data = mw.GetMessageBytes();
     }
     QueueOutgoingMessage(newMessage, false);
 }
 //Called from timeSyncer
 public void SendTimeSync()
 {
     byte[] messageBytes;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<long>(DateTime.UtcNow.Ticks);
         messageBytes = mw.GetMessageBytes();
     }
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.SYNC_TIME_REQUEST;
     newMessage.data = messageBytes;
     QueueOutgoingMessage(newMessage, true);
 }
 //Called from vesselWorker
 public void SendScenarioModuleData(string[] scenarioNames, byte[][] scenarioData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.SCENARIO_DATA;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<string[]>(scenarioNames);
         foreach (byte[] scenarioBytes in scenarioData)
         {
             mw.Write<byte[]>(scenarioBytes);
         }
         newMessage.data = mw.GetMessageBytes();
     }
     DarkLog.Debug("Sending " + scenarioNames.Length + " scenario modules");
     QueueOutgoingMessage(newMessage, false);
 }
 //Called from PlayerColorWorker
 public void SendPlayerColorMessage(byte[] messageData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.PLAYER_COLOR;
     newMessage.data = messageData;
     QueueOutgoingMessage(newMessage, false);
 }
 //Called from networkWorker
 public void SendMotdRequest()
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.MOTD_REQUEST;
     QueueOutgoingMessage(newMessage, true);
 }
 private void SendKerbalsRequest()
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.KERBALS_REQUEST;
     QueueOutgoingMessage(newMessage, true);
 }
 private void SendHeartBeat()
 {
     if (state >= ClientState.CONNECTED && sendMessageQueueHigh.Count == 0)
     {
         if ((UnityEngine.Time.realtimeSinceStartup - lastSendTime) > (Common.HEART_BEAT_INTERVAL / 1000))
         {
             lastSendTime = UnityEngine.Time.realtimeSinceStartup;
             ClientMessage newMessage = new ClientMessage();
             newMessage.type = ClientMessageType.HEARTBEAT;
             QueueOutgoingMessage(newMessage, true);
         }
     }
 }
 private void SendHandshakeRequest()
 {
     byte[] messageBytes;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<int>(Common.PROTOCOL_VERSION);
         mw.Write<string>(Settings.fetch.playerName);
         mw.Write<string>(Settings.fetch.playerGuid.ToString());
         mw.Write<string>(Common.PROGRAM_VERSION);
         messageBytes = mw.GetMessageBytes();
     }
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.HANDSHAKE_REQUEST;
     newMessage.data = messageBytes;
     QueueOutgoingMessage(newMessage, true);
 }
 private void QueueOutgoingMessage(ClientMessage message, bool highPriority)
 {
     lock (messageQueueLock)
     {
         if (highPriority)
         {
             sendMessageQueueHigh.Enqueue(message);
         }
         else
         {
             sendMessageQueueLow.Enqueue(message);
         }
     }
     SendOutgoingMessages();
 }
 //Called from vesselWorker
 public void SendVesselProtoMessage(ProtoVessel vessel, bool isDockingUpdate, bool isFlyingUpdate)
 {
     //Defend against NaN orbits
     if (VesselHasNaNPosition(vessel))
     {
         DarkLog.Debug("Vessel " + vessel.vesselID + " has NaN position");
         return;
     }
     foreach (ProtoPartSnapshot pps in vessel.protoPartSnapshots)
     {
         foreach (ProtoCrewMember pcm in pps.protoModuleCrew.ToArray())
         {
             if (pcm.type == ProtoCrewMember.KerbalType.Tourist)
             {
                 pps.protoModuleCrew.Remove(pcm);
             }
         }
     }
     ConfigNode vesselNode = new ConfigNode();
     vessel.Save(vesselNode);
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.VESSEL_PROTO;
     byte[] vesselBytes = ConfigNodeSerializer.fetch.Serialize(vesselNode);
     File.WriteAllBytes(Path.Combine(KSPUtil.ApplicationRootPath, "lastVessel.txt"), vesselBytes);
     if (vesselBytes != null && vesselBytes.Length > 0)
     {
         UniverseSyncCache.fetch.QueueToCache(vesselBytes);
         using (MessageWriter mw = new MessageWriter())
         {
             mw.Write<double>(Planetarium.GetUniversalTime());
             mw.Write<string>(vessel.vesselID.ToString());
             mw.Write<bool>(isDockingUpdate);
             mw.Write<bool>(isFlyingUpdate);
             mw.Write<byte[]>(Compression.CompressIfNeeded(vesselBytes));
             newMessage.data = mw.GetMessageBytes();
         }
         DarkLog.Debug("Sending vessel " + vessel.vesselID + ", name " + vessel.vesselName + ", type: " + vessel.vesselType + ", size: " + newMessage.data.Length);
         QueueOutgoingMessage(newMessage, false);
     }
     else
     {
         DarkLog.Debug("Failed to create byte[] data for " + vessel.vesselID);
     }
 }
 // Same method as above, only that in this, the message is queued as high priority
 public void SendScenarioModuleDataHighPriority(string[] scenarioNames, byte[][] scenarioData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.SCENARIO_DATA;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<string[]>(scenarioNames);
         foreach (byte[] scenarioBytes in scenarioData)
         {
             mw.Write<byte[]>(Compression.CompressIfNeeded(scenarioBytes));
         }
         newMessage.data = mw.GetMessageBytes();
     }
     DarkLog.Debug("Sending " + scenarioNames.Length + " scenario modules (high priority)");
     QueueOutgoingMessage(newMessage, true);
 }
 //Called from vesselWorker
 public void SendKerbalProtoMessage(ProtoCrewMember kerbal)
 {
     ConfigNode kerbalNode = new ConfigNode();
     kerbal.Save(kerbalNode);
     byte[] kerbalBytes = ConfigNodeSerializer.fetch.Serialize(kerbalNode);
     if (kerbalBytes != null && kerbalBytes.Length > 0)
     {
         ClientMessage newMessage = new ClientMessage();
         newMessage.type = ClientMessageType.KERBAL_PROTO;
         using (MessageWriter mw = new MessageWriter())
         {
             mw.Write<double>(Planetarium.GetUniversalTime());
             mw.Write<string>(kerbal.name);
             mw.Write<byte[]>(kerbalBytes);
             newMessage.data = mw.GetMessageBytes();
         }
         DarkLog.Debug("Sending kerbal " + kerbal.name + ", size: " + newMessage.data.Length);
         QueueOutgoingMessage(newMessage, false);
     }
     else
     {
         DarkLog.Debug("Failed to create byte[] data for kerbal " + kerbal.name);
     }
 }
 //Called from lockSystem
 public void SendLockSystemMessage(byte[] messageData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.LOCK_SYSTEM;
     newMessage.data = messageData;
     QueueOutgoingMessage(newMessage, true);
 }
 private void SendNetworkMessage(ClientMessage message)
 {
     byte[] messageBytes;
     using (MessageWriter mw = new MessageWriter((int)message.type))
     {
         if (message.data != null)
         {
             mw.Write<byte[]>(message.data);
         }
         messageBytes = mw.GetMessageBytes();
     }
     //Disconnect after EndWrite completes
     if (message.type == ClientMessageType.CONNECTION_END)
     {
         using (MessageReader mr = new MessageReader(message.data, false))
         {
             terminateOnNextMessageSend = true;
             connectionEndReason = mr.Read<string>();
         }
     }
     isSendingMessage = true;
     lastSendTime = UnityEngine.Time.realtimeSinceStartup;
     try
     {
         clientConnection.GetStream().BeginWrite(messageBytes, 0, messageBytes.Length, new AsyncCallback(SendCallback), null);
     }
     catch (Exception e)
     {
         HandleDisconnectException(e);
     }
 }
 //Called from chatWorker
 public void SendPingRequest()
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.PING_REQUEST;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<long>(DateTime.UtcNow.Ticks);
         newMessage.data = mw.GetMessageBytes();
     }
     QueueOutgoingMessage(newMessage, true);
 }
 private void SendVesselsRequest(string[] requestList)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.VESSELS_REQUEST;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<string[]>(requestList);
         newMessage.data = mw.GetMessageBytes();
     }
     QueueOutgoingMessage(newMessage, true);
 }
 //Called from PlayerStatusWorker
 public void SendPlayerStatus(PlayerStatus playerStatus)
 {
     byte[] messageBytes;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<string>(playerStatus.playerName);
         mw.Write<string>(playerStatus.vesselText);
         mw.Write<string>(playerStatus.statusText);
         messageBytes = mw.GetMessageBytes();
     }
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.PLAYER_STATUS;
     newMessage.data = messageBytes;
     QueueOutgoingMessage(newMessage, true);
 }
        private void SplitAndRewriteMessage(ref ClientMessage message)
        {
            if (message == null)
            {
                return;
            }
            if (message.data == null)
            {
                return;
            }
            if (message.data.Length > Common.SPLIT_MESSAGE_LENGTH)
            {
                lastSplitMessageType = message.type;
                ClientMessage newSplitMessage = new ClientMessage();
                newSplitMessage.type = ClientMessageType.SPLIT_MESSAGE;
                int splitBytesLeft = message.data.Length;
                using (MessageWriter mw = new MessageWriter())
                {
                    mw.Write<int>((int)message.type);
                    mw.Write<int>(message.data.Length);
                    byte[] firstSplit = new byte[Common.SPLIT_MESSAGE_LENGTH];
                    Array.Copy(message.data, 0, firstSplit, 0, Common.SPLIT_MESSAGE_LENGTH);
                    mw.Write<byte[]>(firstSplit);
                    splitBytesLeft -= Common.SPLIT_MESSAGE_LENGTH;
                    newSplitMessage.data = mw.GetMessageBytes();
                    sendMessageQueueSplit.Enqueue(newSplitMessage);
                }

                while (splitBytesLeft > 0)
                {
                    ClientMessage currentSplitMessage = new ClientMessage();
                    currentSplitMessage.type = ClientMessageType.SPLIT_MESSAGE;
                    currentSplitMessage.data = new byte[Math.Min(splitBytesLeft, Common.SPLIT_MESSAGE_LENGTH)];
                    Array.Copy(message.data, message.data.Length - splitBytesLeft, currentSplitMessage.data, 0, currentSplitMessage.data.Length);
                    splitBytesLeft -= currentSplitMessage.data.Length;
                    sendMessageQueueSplit.Enqueue(currentSplitMessage);
                }
                message = sendMessageQueueSplit.Dequeue();
            }
        }
 //Called from ScreenshotWorker
 public void SendScreenshotMessage(byte[] messageData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.SCREENSHOT_LIBRARY;
     newMessage.data = messageData;
     QueueOutgoingMessage(newMessage, false);
 }
 //Called from ChatWindow
 public void SendChatMessage(byte[] messageData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.CHAT_MESSAGE;
     newMessage.data = messageData;
     QueueOutgoingMessage(newMessage, true);
 }
        //Called from vesselWorker
        public void SendVesselProtoMessage(ProtoVessel vessel, bool isDockingUpdate, bool isFlyingUpdate)
        {
            ConfigNode vesselNode = new ConfigNode();
            ClientMessage newMessage = new ClientMessage();
            newMessage.type = ClientMessageType.VESSEL_PROTO;
            vessel.Save(vesselNode);

            byte[] vesselBytes = ConfigNodeSerializer.fetch.Serialize(vesselNode);

            if (vesselBytes != null && vesselBytes.Length > 0)
            {
                UniverseSyncCache.fetch.SaveToCache(vesselBytes);
                using (MessageWriter mw = new MessageWriter())
                {
                    mw.Write<double>(Planetarium.GetUniversalTime());
                    mw.Write<string>(vessel.vesselID.ToString());
                    mw.Write<bool>(isDockingUpdate);
                    mw.Write<bool>(isFlyingUpdate);
                    mw.Write<byte[]>(vesselBytes);
                    newMessage.data = mw.GetMessageBytes();
                }
                DarkLog.Debug("Sending vessel " + vessel.vesselID + ", name " + vessel.vesselName + ", type: " + vessel.vesselType + ", size: " + newMessage.data.Length);
                QueueOutgoingMessage(newMessage, false);
            }
            else
            {
                DarkLog.Debug("Failed to create byte[] data for " + vessel.vesselID);
            }
        }
 //Called fro craftLibraryWorker
 public void SendCraftLibraryMessage(byte[] messageData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.CRAFT_LIBRARY;
     newMessage.data = messageData;
     QueueOutgoingMessage(newMessage, false);
 }
 //Called from vesselWorker
 public void SendVesselUpdate(VesselUpdate update)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.VESSEL_UPDATE;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<double>(update.planetTime);
         mw.Write<string>(update.vesselID);
         mw.Write<string>(update.bodyName);
         mw.Write<float[]>(update.rotation);
         //mw.Write<float[]>(update.vesselForward);
         //mw.Write<float[]>(update.vesselUp);
         mw.Write<float[]>(update.angularVelocity);
         //FlightState variables
         mw.Write<float>(update.flightState.mainThrottle);
         mw.Write<float>(update.flightState.wheelThrottleTrim);
         mw.Write<float>(update.flightState.X);
         mw.Write<float>(update.flightState.Y);
         mw.Write<float>(update.flightState.Z);
         mw.Write<bool>(update.flightState.killRot);
         mw.Write<bool>(update.flightState.gearUp);
         mw.Write<bool>(update.flightState.gearDown);
         mw.Write<bool>(update.flightState.headlight);
         mw.Write<float>(update.flightState.wheelThrottle);
         mw.Write<float>(update.flightState.fastThrottle);
         mw.Write<float>(update.flightState.roll);
         mw.Write<float>(update.flightState.yaw);
         mw.Write<float>(update.flightState.pitch);
         mw.Write<float>(update.flightState.rollTrim);
         mw.Write<float>(update.flightState.yawTrim);
         mw.Write<float>(update.flightState.pitchTrim);
         mw.Write<float>(update.flightState.wheelSteer);
         mw.Write<float>(update.flightState.wheelSteerTrim);
         //Action group controls
         mw.Write<bool[]>(update.actiongroupControls);
         //Position/velocity
         mw.Write<bool>(update.isSurfaceUpdate);
         if (update.isSurfaceUpdate)
         {
             mw.Write<double[]>(update.position);
             mw.Write<double[]>(update.velocity);
         }
         else
         {
             mw.Write<double[]>(update.orbit);
         }
         newMessage.data = mw.GetMessageBytes();
     }
     QueueOutgoingMessage(newMessage, false);
 }
 //Called from main
 public void SendDisconnect(string disconnectReason = "Unknown")
 {
     if (state != ClientState.DISCONNECTING && state >= ClientState.CONNECTED)
     {
         DarkLog.Debug("Sending disconnect message, reason: " + disconnectReason);
         Client.fetch.status = "Disconnected: " + disconnectReason;
         state = ClientState.DISCONNECTING;
         byte[] messageBytes;
         using (MessageWriter mw = new MessageWriter())
         {
             mw.Write<string>(disconnectReason);
             messageBytes = mw.GetMessageBytes();
         }
         ClientMessage newMessage = new ClientMessage();
         newMessage.type = ClientMessageType.CONNECTION_END;
         newMessage.data = messageBytes;
         QueueOutgoingMessage(newMessage, true);
     }
 }
        private static void HandleMessage(ClientObject client, ClientMessage message)
        {
            //Prevent plugins from dodging SPLIT_MESSAGE. If they are modified, every split message will be broken.
            if (message.type != ClientMessageType.SPLIT_MESSAGE)
            {
                DMPPluginHandler.FireOnMessageReceived(client, message);

                if (message.handled)
                {
                    //a plugin has handled this message and requested suppression of the default DMP behavior
                    return;
                }
            }

            //Clients can only send HEARTBEATS, HANDSHAKE_REQUEST or CONNECTION_END's until they are authenticated.
            if (!client.authenticated && !(message.type == ClientMessageType.HEARTBEAT || message.type == ClientMessageType.HANDSHAKE_RESPONSE || message.type == ClientMessageType.CONNECTION_END))
            {
                SendConnectionEnd(client, "You must authenticate before attempting to send a " + message.type.ToString() + " message");
                return;
            }

            try
            {
                switch (message.type)
                {
                    case ClientMessageType.HEARTBEAT:
                        //Don't do anything for heartbeats, they just keep the connection alive
                        break;
                    case ClientMessageType.HANDSHAKE_RESPONSE:
                        HandleHandshakeResponse(client, message.data);
                        break;
                    case ClientMessageType.CHAT_MESSAGE:
                        HandleChatMessage(client, message.data);
                        break;
                    case ClientMessageType.PLAYER_STATUS:
                        HandlePlayerStatus(client, message.data);
                        break;
                    case ClientMessageType.PLAYER_COLOR:
                        HandlePlayerColor(client, message.data);
                        break;
                    case ClientMessageType.SCENARIO_DATA:
                        HandleScenarioModuleData(client, message.data);
                        break;
                    case ClientMessageType.SYNC_TIME_REQUEST:
                        HandleSyncTimeRequest(client, message.data);
                        break;
                    case ClientMessageType.KERBALS_REQUEST:
                        HandleKerbalsRequest(client);
                        break;
                    case ClientMessageType.KERBAL_PROTO:
                        HandleKerbalProto(client, message.data);
                        break;
                    case ClientMessageType.VESSELS_REQUEST:
                        HandleVesselsRequest(client, message.data);
                        break;
                    case ClientMessageType.VESSEL_PROTO:
                        HandleVesselProto(client, message.data);
                        break;
                    case ClientMessageType.VESSEL_UPDATE:
                        HandleVesselUpdate(client, message.data);
                        break;
                    case ClientMessageType.VESSEL_REMOVE:
                        HandleVesselRemoval(client, message.data);
                        break;
                    case ClientMessageType.CRAFT_LIBRARY:
                        HandleCraftLibrary(client, message.data);
                        break;
                    case ClientMessageType.SCREENSHOT_LIBRARY:
                        HandleScreenshotLibrary(client, message.data);
                        break;
                    case ClientMessageType.FLAG_SYNC:
                        HandleFlagSync(client, message.data);
                        break;
                    case ClientMessageType.PING_REQUEST:
                        HandlePingRequest(client, message.data);
                        break;
                    case ClientMessageType.MOTD_REQUEST:
                        HandleMotdRequest(client);  
                        break;
                    case ClientMessageType.WARP_CONTROL:
                        HandleWarpControl(client, message.data);
                        break;
                    case ClientMessageType.LOCK_SYSTEM:
                        HandleLockSystemMessage(client, message.data);
                        break;
                    case ClientMessageType.MOD_DATA:
                        HandleModDataMessage(client, message.data);
                        break;
                    case ClientMessageType.SPLIT_MESSAGE:
                        HandleSplitMessage(client, message.data);
                        break;
                    case ClientMessageType.CONNECTION_END:
                        HandleConnectionEnd(client, message.data);
                        break;
                    default:
                        DarkLog.Debug("Unhandled message type " + message.type);
                        SendConnectionEnd(client, "Unhandled message type " + message.type);
                        break;
                }
            }
            catch (Exception e)
            {
                DarkLog.Debug("Error handling " + message.type + " from " + client.playerName + ", exception: " + e);
                SendConnectionEnd(client, "Server failed to process " + message.type + " message");
            }
        }
 //Called from FlagSyncer
 public void SendFlagMessage(byte[] messageData)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.FLAG_SYNC;
     newMessage.data = messageData;
     QueueOutgoingMessage(newMessage, false);
 }