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; } }
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); }