public override void ProcessPacket(TrashSystemNewTrashCreatedPacket packet, NebulaConnection conn) { bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { int myId = Multiplayer.Session.World.GenerateTrashOnPlayer(packet); //Check if myID is same as the ID from the host if (myId != packet.TrashId) { Multiplayer.Session.Trashes.SwitchTrashWithIds(myId, packet.TrashId); } } }
public override void ProcessPacket(MilestoneUnlockPacket packet, NebulaConnection conn) { IPlayerManager playerManager = Multiplayer.Session.Network.PlayerManager; bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { using (Multiplayer.Session.Statistics.IsIncomingRequest.On()) { if (GameMain.data.milestoneSystem.milestoneDatas.TryGetValue(packet.Id, out MilestoneData milestoneData)) { milestoneData.journalData.patternId = packet.PatternId; milestoneData.journalData.parameters = packet.Parameters; GameMain.data.milestoneSystem.UnlockMilestone(packet.Id, packet.UnlockTick); } } } }
public override void ProcessPacket(NewDroneOrderPacket packet, NebulaConnection conn) { // Host does not need to know about flying drones of other players if he is not on the same planet if (IsHost) { if (GameMain.mainPlayer.planetId != packet.PlanetId) { return; } INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { if (packet.Stage == 1 || packet.Stage == 2) { Multiplayer.Session.Drones.AddPlayerDronePlan(player.Id, packet.EntityId); } else if (packet.Stage == 3) { Multiplayer.Session.Drones.RemovePlayerDronePlan(player.Id, packet.EntityId); } } } Multiplayer.Session.World.UpdateRemotePlayerDrone(packet); }
public override void ProcessPacket(GameHistoryNotificationPacket packet, NebulaConnection conn) { bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { using (Multiplayer.Session.History.IsIncomingRequest.On()) { switch (packet.Event) { case GameHistoryEvent.ResumeQueue: GameMain.history.ResumeTechQueue(); break; case GameHistoryEvent.PauseQueue: GameMain.history.PauseTechQueue(); break; } } } }
public override void ProcessPacket(ChatCommandWhisperPacket packet, NebulaConnection conn) { if (IsClient) { WhisperCommandHandler.SendWhisperToLocalPlayer(packet.SenderUsername, packet.Message); } else { // two cases, simplest is that whisper is meant for host if (Multiplayer.Session.LocalPlayer.Data.Username == packet.RecipientUsername) { WhisperCommandHandler.SendWhisperToLocalPlayer(packet.SenderUsername, packet.Message); return; } // second case, relay message to recipient INebulaPlayer recipient = Multiplayer.Session.Network .PlayerManager.GetConnectedPlayerByUsername(packet.RecipientUsername); if (recipient == null) { Log.Warn($"Recipient not found {packet.RecipientUsername}"); INebulaPlayer sender = Multiplayer.Session.Network.PlayerManager.GetPlayer(conn); sender.SendPacket(new ChatCommandWhisperPacket("SYSTEM", packet.SenderUsername, $"User not found {packet.RecipientUsername}")); return; } recipient.SendPacket(packet); } }
public override void ProcessPacket(GameHistoryRemoveTechPacket packet, NebulaConnection conn) { bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { using (Multiplayer.Session.History.IsIncomingRequest.On()) { int index = System.Array.IndexOf(GameMain.history.techQueue, packet.TechId); //sanity: packet wanted to remove tech, which is not queued on this client, ignore it if (index < 0) { Log.Warn($"ProcessPacket: TechId: {packet.TechId} was not in queue, discarding packet"); return; } GameMain.history.RemoveTechInQueue(index); } } }
public override void ProcessPacket(StatisticsRequestEvent packet, NebulaConnection conn) { if (IsClient) { return; } INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { if (packet.Event == StatisticEvent.WindowOpened) { Multiplayer.Session.Statistics.RegisterPlayer(conn, player.Id); using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { Multiplayer.Session.Statistics.ExportAllData(writer.BinaryWriter); conn.SendPacket(new StatisticsDataPacket(writer.CloseAndGetBytes())); } } else if (packet.Event == StatisticEvent.WindowClosed) { Multiplayer.Session.Statistics.UnRegisterPlayer(player.Id); } } }
public override void ProcessPacket(PlayerMovement packet, NebulaConnection conn) { bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { player.Data.LocalPlanetId = packet.LocalPlanetId; player.Data.UPosition = packet.UPosition; player.Data.Rotation = packet.Rotation; player.Data.BodyRotation = packet.BodyRotation; player.Data.LocalPlanetPosition = packet.LocalPlanetPosition; playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { Multiplayer.Session.World.UpdateRemotePlayerPosition(packet); } }
public override void ProcessPacket(TrashSystemClearAllTrashPacket packet, NebulaConnection conn) { bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { using (Multiplayer.Session.Trashes.ClearAllTrashFromOtherPlayers.On()) { GameMain.data.trashSystem.ClearAllTrash(); } } }
public override void ProcessPacket(FactoryLoadRequest packet, NebulaConnection conn) { if (IsClient) { return; } PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetID); PlanetFactory factory = GameMain.data.GetOrCreateFactory(planet); using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { factory.Export(writer.BinaryWriter); byte[] data = writer.CloseAndGetBytes(); Log.Info($"Sent {data.Length} bytes of data for PlanetFactory {planet.name} (ID: {planet.id})"); conn.SendPacket(new FactoryData(packet.PlanetID, data, planet.data.modData)); } // Add requesting client to connected player, so he can receive following update IPlayerManager playerManager = Multiplayer.Session.Network.PlayerManager; INebulaPlayer player = playerManager.GetSyncingPlayer(conn); if (player != null) { player.Data.LocalPlanetId = packet.PlanetID; player.Data.LocalStarId = GameMain.galaxy.PlanetById(packet.PlanetID).star.id; using (playerManager.GetConnectedPlayers(out System.Collections.Generic.Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { connectedPlayers.Add(player.Connection, player); } } }
public override void ProcessPacket(NewChatMessagePacket packet, NebulaConnection conn) { if (ChatManager.Instance == null) { Log.Warn($"Unable to process chat packet, chat window assets were not loaded properly"); return; } if (IsHost) { INebulaPlayer player = Multiplayer.Session.Network.PlayerManager?.GetPlayer(conn); Multiplayer.Session.Network.PlayerManager?.SendPacketToOtherPlayers(packet, player); } DateTime sentAt = packet.SentAt == 0 ? DateTime.Now : DateTime.FromBinary(packet.SentAt); if (string.IsNullOrEmpty(packet.UserName)) { ChatManager.Instance.SendChatMessage($"[{sentAt:HH:mm}] {packet.MessageText}", packet.MessageType); } else { ChatManager.Instance.SendChatMessage($"[{sentAt:HH:mm}] [{packet.UserName}] : {packet.MessageText}", packet.MessageType); } }
public override void ProcessPacket(PlanetFactory factory, PlayerAction_Build actionBuild, RedoRequestPacket packet, INebulaConnection conn) { INebulaPlayer player = NebulaModAPI.MultiplayerSession.Network.PlayerManager.GetPlayer(conn); if (UndoManager.undos[player.Id].TryRedo(out string message, out bool sound)) { conn.SendPacket(new ActionResultPacket(message, sound)); } }
public void SendPacketToAllPlayers <T>(T packet) where T : class, new() { using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { INebulaPlayer player = kvp.Value; player.SendPacket(packet); } } }
public override void ProcessPacket(PlayerUpdateLocalStarId packet, NebulaConnection conn) { if (IsClient) { return; } INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { player.Data.LocalStarId = packet.StarId; } }
public void SendRawPacketToPlanet(byte[] rawPacket, int planetId, INebulaConnection sender) { using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { INebulaPlayer player = kvp.Value; if (player.Data.LocalPlanetId == planetId && (NebulaConnection)player.Connection != (NebulaConnection)sender) { ((NebulaPlayer)player).SendRawPacket(rawPacket); } } } }
public void SendPacketToStarExcept <T>(T packet, int starId, INebulaConnection exclude) where T : class, new() { using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { INebulaPlayer player = kvp.Value; if (player.Data.LocalStarId == starId && player != GetPlayer(exclude)) { player.SendPacket(packet); } } } }
public void SendPacketToPlanet <T>(T packet, int planetId) where T : class, new() { using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { INebulaPlayer player = kvp.Value; if (player.Data.LocalPlanetId == planetId) { player.SendPacket(packet); } } } }
public void SendPacketToLocalStar <T>(T packet) where T : class, new() { using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { INebulaPlayer player = kvp.Value; if (player.Data.LocalStarId == GameMain.data.localStar?.id) { player.SendPacket(packet); } } } }
public static void SendToOtherPlayersOnTheSamePlanet <T>(NebulaConnection originator, T packet, int planetId) where T : class, new() { //Send to players on the same planet using (((NetworkProvider)Multiplayer.Session.Network).PlayerManager.GetConnectedPlayers(out System.Collections.Generic.Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (System.Collections.Generic.KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { NebulaConnection connection = (NebulaConnection)kvp.Key; INebulaPlayer player = kvp.Value; if (player.Data.LocalPlanetId == planetId && connection != originator) { connection.SendPacket(packet); } } } }
public override void ProcessPacket(StarBroadcastPacket packet, NebulaConnection conn) { if (IsClient) { return; } INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null && packet.PacketObject != null) { //Forward packet to other users playerManager.SendRawPacketToStar(packet.PacketObject, packet.StarId, conn); ((NetworkProvider)Multiplayer.Session.Network).PacketProcessor.EnqueuePacketForProcessing(packet.PacketObject, conn); } }
public override void ProcessPacket(NameInputPacket packet, NebulaConnection conn) { if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToOtherPlayers(packet, player); } } using (Multiplayer.Session.Factories.IsIncomingRequest.On()) { // If in lobby, apply change to UI galaxy GalaxyData galaxyData = Multiplayer.Session.IsInLobby ? UIRoot.instance.galaxySelect.starmap.galaxyData : GameMain.galaxy; if (galaxyData == null) { return; } for (int i = 0; i < packet.Names.Length; i++) { if (packet.StarIds[i] != NebulaModAPI.STAR_NONE) { StarData star = galaxyData.StarById(packet.StarIds[i]); star.overrideName = packet.Names[i]; star.NotifyOnDisplayNameChange(); Log.Debug($"star{star.id}: {star.name} -> {star.overrideName}"); } else { PlanetData planet = galaxyData.PlanetById(packet.PlanetIds[i]); planet.overrideName = packet.Names[i]; planet.NotifyOnDisplayNameChange(); Log.Debug($"planet{planet.id}: {planet.name} -> {planet.overrideName}"); } } galaxyData.NotifyAstroNameChange(); if (Multiplayer.Session.IsInLobby) { // Refresh star name in lobby UIRoot.instance.galaxySelect.starmap.OnGalaxyDataReset(); } } }
public void SendTechRefundPackagesToClients(int techId) { //send players their contributions back using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { INebulaPlayer curPlayer = kvp.Value; long techProgress = ((NebulaPlayer)curPlayer).ReleaseResearchProgress(); if (techProgress > 0) { Log.Info($"Sending Recover request for player {curPlayer.Id}: refunding for techId {techId} - raw progress: {curPlayer.TechProgressContributed}"); GameHistoryTechRefundPacket refundPacket = new GameHistoryTechRefundPacket(techId, techProgress); curPlayer.SendPacket(refundPacket); } } } }
public override void ProcessPacket(ChatCommandWhoPacket packet, NebulaConnection conn) { if (IsHost) { IPlayerData[] playerDatas = Multiplayer.Session.Network.PlayerManager.GetAllPlayerDataIncludingHost(); ILocalPlayer hostPlayer = Multiplayer.Session.LocalPlayer; string resultPayload = WhoCommandHandler.BuildResultPayload(playerDatas, hostPlayer); INebulaPlayer recipient = Multiplayer.Session.Network.PlayerManager.GetPlayer(conn); recipient.SendPacket(new ChatCommandWhoPacket(false, resultPayload)); } else { if (packet.IsRequest) { Log.Warn("Request packet received for who response"); } ChatManager.Instance.SendChatMessage(packet.ResponsePayload, ChatMessageType.CommandOutputMessage); } }
public override void ProcessPacket(GameHistoryEnqueueTechPacket packet, NebulaConnection conn) { if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { using (Multiplayer.Session.History.IsIncomingRequest.On()) { GameMain.history.EnqueueTech(packet.TechId); } playerManager.SendPacketToOtherPlayers(packet, player); } } else { using (Multiplayer.Session.History.IsIncomingRequest.On()) { GameMain.history.EnqueueTech(packet.TechId); } } }
public override void ProcessPacket(StationUI packet, NebulaConnection conn) { if (IsHost) { // always update values for host packet.ShouldRefund = false; Multiplayer.Session.StationsUI.UpdateStation(ref packet); // broadcast to other clients INebulaPlayer player = playerManager.GetPlayer(conn); playerManager.SendPacketToOtherPlayers(packet, player); // as we block the normal method for the client he must run it once he receives this packet. // but only the one issued the request should get items refund packet.ShouldRefund = true; conn.SendPacket(packet); } if (IsClient) { Multiplayer.Session.StationsUI.UpdateStation(ref packet); } }
public override void ProcessPacket(PlayerAnimationUpdate packet, NebulaConnection conn) { bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { packet.PlayerId = player.Id; playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { Multiplayer.Session.World.UpdateRemotePlayerAnimation(packet); } }
public override void ProcessPacket(PlayerColorChanged packet, NebulaConnection conn) { bool valid = true; if (IsHost) { INebulaPlayer player = playerManager.GetPlayer(conn); if (player != null) { player.Data.MechaColors = packet.Colors; playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { Multiplayer.Session.World.UpdatePlayerColor(packet.PlayerId, packet.Colors); } }
public override void ProcessPacket(ILSRequestgStationPoolSync packet, NebulaConnection conn) { if (IsClient) { return; } INebulaPlayer player = playerManager.GetPlayer(conn); if (player == null) { player = playerManager.GetSyncingPlayer(conn); } if (player != null) { int countILS = 0; int iter = 0; foreach (StationComponent stationComponent in GameMain.data.galacticTransport.stationPool) { if (stationComponent != null) { countILS++; } } if (countILS == 0) { return; } int[] stationGId = new int[countILS]; int[] stationMaxShipCount = new int[countILS]; int[] stationId = new int[countILS]; Float3[] DockPos = new Float3[countILS]; Float4[] DockRot = new Float4[countILS]; int[] planetId = new int[countILS]; int[] workShipCount = new int[countILS]; int[] idleShipCount = new int[countILS]; ulong[] workShipIndices = new ulong[countILS]; ulong[] idleShipIndices = new ulong[countILS]; List <int> shipStage = new List <int>(); List <int> shipDirection = new List <int>(); List <float> shipWarpState = new List <float>(); List <int> shipWarperCnt = new List <int>(); List <int> shipItemID = new List <int>(); List <int> shipItemCount = new List <int>(); List <int> shipPlanetA = new List <int>(); List <int> shipPlanetB = new List <int>(); List <int> shipOtherGId = new List <int>(); List <float> shipT = new List <float>(); List <int> shipIndex = new List <int>(); List <Double3> shipPos = new List <Double3>(); List <Float4> shipRot = new List <Float4>(); List <Float3> shipVel = new List <Float3>(); List <float> shipSpeed = new List <float>(); List <Float3> shipAngularVel = new List <Float3>(); List <Double3> shipPPosTemp = new List <Double3>(); List <Float4> shipPRotTemp = new List <Float4>(); foreach (StationComponent stationComponent in GameMain.data.galacticTransport.stationPool) { if (stationComponent != null) { stationGId[iter] = stationComponent.gid; stationMaxShipCount[iter] = stationComponent.workShipDatas.Length; stationId[iter] = stationComponent.id; DockPos[iter] = new Float3(stationComponent.shipDockPos); DockRot[iter] = new Float4(stationComponent.shipDockRot); planetId[iter] = stationComponent.planetId; workShipCount[iter] = stationComponent.workShipCount; idleShipCount[iter] = stationComponent.idleShipCount; workShipIndices[iter] = stationComponent.workShipIndices; idleShipIndices[iter] = stationComponent.idleShipIndices; // ShipData is never null for (int j = 0; j < stationComponent.workShipDatas.Length; j++) { ShipData shipData = stationComponent.workShipDatas[j]; shipStage.Add(shipData.stage); shipDirection.Add(shipData.direction); shipWarpState.Add(shipData.warpState); shipWarperCnt.Add(shipData.warperCnt); shipItemID.Add(shipData.itemId); shipItemCount.Add(shipData.itemCount); shipPlanetA.Add(shipData.planetA); shipPlanetB.Add(shipData.planetB); shipOtherGId.Add(shipData.otherGId); shipT.Add(shipData.t); shipIndex.Add(shipData.shipIndex); shipPos.Add(new Double3(shipData.uPos.x, shipData.uPos.y, shipData.uPos.z)); shipRot.Add(new Float4(shipData.uRot)); shipVel.Add(new Float3(shipData.uVel)); shipSpeed.Add(shipData.uSpeed); shipAngularVel.Add(new Float3(shipData.uAngularVel)); shipPPosTemp.Add(new Double3(shipData.pPosTemp.x, shipData.pPosTemp.y, shipData.pPosTemp.z)); shipPRotTemp.Add(new Float4(shipData.pRotTemp)); } iter++; } } ILSgStationPoolSync packet2 = new ILSgStationPoolSync( stationGId, stationMaxShipCount, stationId, DockPos, DockRot, planetId, workShipCount, idleShipCount, workShipIndices, idleShipIndices, shipStage.ToArray(), shipDirection.ToArray(), shipWarpState.ToArray(), shipWarperCnt.ToArray(), shipItemID.ToArray(), shipItemCount.ToArray(), shipPlanetA.ToArray(), shipPlanetB.ToArray(), shipOtherGId.ToArray(), shipT.ToArray(), shipIndex.ToArray(), shipPos.ToArray(), shipRot.ToArray(), shipVel.ToArray(), shipSpeed.ToArray(), shipAngularVel.ToArray(), shipPPosTemp.ToArray(), shipPRotTemp.ToArray()); player.SendPacket(packet2); } }
public override void ProcessPacket(ILSArriveStarPlanetRequest packet, NebulaConnection conn) { if (IsClient) { return; } INebulaPlayer player = playerManager.GetPlayer(conn); if (player == null) { player = playerManager.GetSyncingPlayer(conn); } if (player != null) { List <int> stationGId = new List <int>(); List <int> stationPId = new List <int>(); List <int> stationMaxShips = new List <int>(); List <int> storageLength = new List <int>(); List <int> slotLength = new List <int>(); int arraySizeStorage = 0; int arraySizeSlot = 0; int offsetStorage = 0; int offsetSlot = 0; foreach (StationComponent stationComponent in GameMain.data.galacticTransport.stationPool) { if (stationComponent != null && GameMain.galaxy.PlanetById(stationComponent.planetId)?.star.id == packet.StarId) { stationGId.Add(stationComponent.gid); stationPId.Add(stationComponent.planetId); stationMaxShips.Add(stationComponent.workShipDatas.Length); storageLength.Add(stationComponent.storage.Length); slotLength.Add(stationComponent.slots.Length); } } if (stationGId.Count > 0) { StationComponent[] gStationPool = GameMain.data.galacticTransport.stationPool; for (int i = 0; i < storageLength.Count; i++) { arraySizeStorage += storageLength[i]; } for (int i = 0; i < slotLength.Count; i++) { arraySizeSlot += slotLength[i]; } int[] storageIdx = new int[arraySizeSlot]; int[] itemId = new int[arraySizeStorage]; int[] count = new int[arraySizeStorage]; int[] inc = new int[arraySizeStorage]; for (int i = 0; i < stationGId.Count; i++) { for (int j = 0; j < slotLength[i]; j++) { if (gStationPool[stationGId[i]].slots.Length > 0) // collectors dont have a slot for belts { storageIdx[offsetSlot + j] = gStationPool[stationGId[i]].slots[j].storageIdx; } } offsetSlot += slotLength[i]; for (int j = 0; j < storageLength[i]; j++) { itemId[offsetStorage + j] = gStationPool[stationGId[i]].storage[j].itemId; count[offsetStorage + j] = gStationPool[stationGId[i]].storage[j].count; inc[offsetStorage + j] = gStationPool[stationGId[i]].storage[j].inc; } offsetStorage += storageLength[i]; } player.SendPacket(new ILSArriveStarPlanetResponse(stationGId.ToArray(), stationPId.ToArray(), stationMaxShips.ToArray(), storageLength.ToArray(), storageIdx, slotLength.ToArray(), itemId, count, inc)); } } }
public void PlayerDisconnected(INebulaConnection conn) { INebulaPlayer player = null; bool playerWasSyncing = false; int syncCount = -1; Multiplayer.Session.NumPlayers -= 1; DiscordManager.UpdateRichPresence(); using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { if (connectedPlayers.TryGetValue(conn, out INebulaPlayer removingPlayer)) { player = removingPlayer; connectedPlayers.Remove(conn); } } using (GetPendingPlayers(out Dictionary <INebulaConnection, INebulaPlayer> pendingPlayers)) { if (pendingPlayers.TryGetValue(conn, out INebulaPlayer removingPlayer)) { player = removingPlayer; pendingPlayers.Remove(conn); } } using (GetSyncingPlayers(out Dictionary <INebulaConnection, INebulaPlayer> syncingPlayers)) { if (syncingPlayers.TryGetValue(conn, out INebulaPlayer removingPlayer)) { player = removingPlayer; syncingPlayers.Remove(conn); playerWasSyncing = true; syncCount = syncingPlayers.Count; } } if (player != null) { SendPacketToOtherPlayers(new PlayerDisconnected(player.Id, Multiplayer.Session.NumPlayers), player); NebulaModAPI.OnPlayerLeftGame?.Invoke(player.Data); Multiplayer.Session.World.DestroyRemotePlayerModel(player.Id); using (threadSafe.availablePlayerIds.GetLocked(out Queue <ushort> availablePlayerIds)) { availablePlayerIds.Enqueue(player.Id); } Multiplayer.Session.Statistics.UnRegisterPlayer(player.Id); Multiplayer.Session.DysonSpheres.UnRegisterPlayer(conn); //Notify players about queued building plans for drones int[] DronePlans = Multiplayer.Session.Drones.GetPlayerDronePlans(player.Id); if (DronePlans != null && DronePlans.Length > 0 && player.Data.LocalPlanetId > 0) { Multiplayer.Session.Network.SendPacketToPlanet(new RemoveDroneOrdersPacket(DronePlans), player.Data.LocalPlanetId); //Remove it also from host queue, if host is on the same planet if (GameMain.mainPlayer.planetId == player.Data.LocalPlanetId) { for (int i = 0; i < DronePlans.Length; i++) { GameMain.mainPlayer.mecha.droneLogic.serving.Remove(DronePlans[i]); } } } if (playerWasSyncing && syncCount == 0) { Multiplayer.Session.Network.SendPacket(new SyncComplete()); Multiplayer.Session.World.OnAllPlayersSyncCompleted(); } else if (Config.Options.SyncSoil) { GameMain.mainPlayer.sandCount -= player.Data.Mecha.SandCount; UIRoot.instance.uiGame.OnSandCountChanged(GameMain.mainPlayer.sandCount, -player.Data.Mecha.SandCount); Multiplayer.Session.Network.SendPacket(new PlayerSandCount(GameMain.mainPlayer.sandCount)); } } else { Log.Warn($"PlayerDisconnected NOT CALLED!"); if (Config.Options.SyncSoil) { // now we need to recalculate the current sand amount :C GameMain.mainPlayer.sandCount = Multiplayer.Session.LocalPlayer.Data.Mecha.SandCount; using (GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> entry in connectedPlayers) { GameMain.mainPlayer.sandCount += entry.Value.Data.Mecha.SandCount; } } UIRoot.instance.uiGame.OnSandCountChanged(GameMain.mainPlayer.sandCount, GameMain.mainPlayer.sandCount - Multiplayer.Session.LocalPlayer.Data.Mecha.SandCount); Multiplayer.Session.Network.SendPacket(new PlayerSandCount(GameMain.mainPlayer.sandCount)); } } }