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(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 void SendBroadcastIfNeeded() { if (!IsStatisticsNeeded) { return; } using (instance.GetRequestors(out var requestors)) { if (requestors.Count > 0) { //Export and prepare update packet StatisticUpdateDataPacket updatePacket; using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { ExportCurrentTickData(writer.BinaryWriter); updatePacket = new StatisticUpdateDataPacket(writer.CloseAndGetBytes()); } //Broadcast the update packet to the people with opened statistic window foreach (var player in requestors) { player.Value.SendPacket(updatePacket); } ClearCapturedData(); } } }
public override void ProcessPacket(GlobalGameDataRequest packet, NebulaConnection conn) { if (IsClient) { return; } //Export GameHistoryData, TrashSystem, MilestoneSystem //PlanetFactory, Dysonsphere, GalacticTransport will be handle else where using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.history.Export(writer.BinaryWriter); conn.SendPacket(new GameHistoryDataResponse(writer.CloseAndGetBytes())); } using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.data.trashSystem.Export(writer.BinaryWriter); conn.SendPacket(new TrashSystemResponseDataPacket(writer.CloseAndGetBytes())); } using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.data.milestoneSystem.Export(writer.BinaryWriter); conn.SendPacket(new MilestoneDataResponse(writer.CloseAndGetBytes())); } }
public void ProcessPacket(TrashSystemRequestDataPacket packet, NebulaConnection conn) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.data.trashSystem.Export(writer.BinaryWriter); conn.SendPacket(new TrashSystemResponseDataPacket(writer.CloseAndGetBytes())); } }
public void ProcessPacket(GameHistoryDataRequest packet, NebulaConnection conn) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.history.Export(writer.BinaryWriter); conn.SendPacket(new GameHistoryDataResponse(writer.CloseAndGetBytes())); } }
public AddEntityPreviewRequest(int planetId, PrebuildData prebuild) { PlanetId = planetId; using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { prebuild.Export(writer.BinaryWriter); PrebuildDataRaw = writer.CloseAndGetBytes(); } }
public void ProcessPacket(DysonSphereLoadRequest packet, NebulaConnection conn) { DysonSphere dysonSphere = GameMain.data.CreateDysonSphere(packet.StarIndex); using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { dysonSphere.Export(writer.BinaryWriter); conn.SendPacket(new DysonSphereData(packet.StarIndex, writer.CloseAndGetBytes())); } }
public static void OnClose_Postfix() { if (Multiplayer.IsActive && Multiplayer.Session.LocalPlayer.IsClient) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.mainPlayer.mecha.diyAppearance.Export(writer.BinaryWriter); Multiplayer.Session.Network.SendPacket(new PlayerMechaDIYArmor(writer.CloseAndGetBytes(), GameMain.mainPlayer.mecha.diyItems.items.Keys.ToArray(), GameMain.mainPlayer.mecha.diyItems.items.Values.ToArray())); } } }
public void ProcessPacket(FactoryLoadRequest packet, NebulaConnection conn) { PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetID); PlanetFactory factory = GameMain.data.GetOrCreateFactory(planet); using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { factory.Export(writer.BinaryWriter); conn.SendPacket(new FactoryData(packet.PlanetID, writer.CloseAndGetBytes())); } conn.SendPacket(StatisticsManager.instance.GetFactoryPlanetIds()); }
public static byte[] GS2GetSettings() { byte[] compressedSettings = null; using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { writer.BinaryWriter.Write((String)GS2_GSSettings.GetMethod("Serialize").Invoke(GS2_GSSettings.GetProperty("Instance"), null)); compressedSettings = writer.CloseAndGetBytes(); } return(compressedSettings); }
public override void ProcessPacket(MilestoneDataRequest packet, NebulaConnection conn) { if (IsClient) { return; } using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.data.milestoneSystem.Export(writer.BinaryWriter); conn.SendPacket(new MilestoneDataResponse(writer.CloseAndGetBytes())); } }
public override void ProcessPacket(PlanetDataRequest packet, NebulaConnection conn) { if (IsClient) { return; } Dictionary <int, byte[]> planetDataToReturn = new Dictionary <int, byte[]>(); foreach (int planetId in packet.PlanetIDs) { PlanetData planet = GameMain.galaxy.PlanetById(planetId); Log.Info($"Returning terrain for {planet.name}"); // NOTE: The following has been picked-n-mixed from "PlanetModelingManager.PlanetComputeThreadMain()" // This method is **costly** - do not run it more than is required! // It generates the planet on the host and then sends it to the client PlanetAlgorithm planetAlgorithm = PlanetModelingManager.Algorithm(planet); if (planet.data == null) { planet.data = new PlanetRawData(planet.precision); planet.modData = planet.data.InitModData(planet.modData); planet.data.CalcVerts(); planet.aux = new PlanetAuxData(planet); planetAlgorithm.GenerateTerrain(planet.mod_x, planet.mod_y); planetAlgorithm.CalcWaterPercent(); //Load planet meshes and register callback to unload unneccessary stuff planet.wanted = true; planet.onLoaded += OnActivePlanetLoaded; PlanetModelingManager.modPlanetReqList.Enqueue(planet); if (planet.type != EPlanetType.Gas) { planetAlgorithm.GenerateVegetables(); planetAlgorithm.GenerateVeins(false); } } using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { planet.ExportRuntime(writer.BinaryWriter); planetDataToReturn.Add(planetId, writer.CloseAndGetBytes()); } } conn.SendPacket(new PlanetDataResponse(planetDataToReturn)); }
public CreatePrebuildsRequest(int planetId, List <BuildPreview> buildPreviews, int playerId, string buildToolType) { AuthorId = playerId; PlanetId = planetId; BuildToolType = buildToolType; using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { writer.BinaryWriter.Write(buildPreviews.Count); for (int i = 0; i < buildPreviews.Count; i++) { SerializeBuildPreview(buildPreviews[i], buildPreviews, writer.BinaryWriter); } BuildPreviewData = writer.CloseAndGetBytes(); } }
public CreatePrebuildsRequest(int planetId, List <BuildPreview> buildPreviews, Pose pose) { PlanetId = planetId; PosePosition = new Float3(pose.position); PoseRotation = new Float4(pose.rotation); using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { writer.BinaryWriter.Write(buildPreviews.Count); for (int i = 0; i < buildPreviews.Count; i++) { SerializeBuildPreview(buildPreviews[i], buildPreviews, writer.BinaryWriter); } BuildPreviewData = writer.CloseAndGetBytes(); } }
public override void ProcessPacket(DysonSphereLoadRequest packet, NebulaConnection conn) { if (IsClient) { return; } switch (packet.Event) { case DysonSphereRequestEvent.List: using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { List <int> list = new List <int>(); for (int i = 0; i < GameMain.data.dysonSpheres.Length; ++i) { if (GameMain.data.dysonSpheres[i] != null) { list.Add(i); } } writer.BinaryWriter.Write(list.Count); foreach (int starIndex in list) { writer.BinaryWriter.Write(starIndex); } conn.SendPacket(new DysonSphereData(packet.StarIndex, writer.CloseAndGetBytes(), DysonSphereRespondEvent.List)); } break; case DysonSphereRequestEvent.Load: DysonSphere dysonSphere = GameMain.data.CreateDysonSphere(packet.StarIndex); using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { dysonSphere.Export(writer.BinaryWriter); byte[] data = writer.CloseAndGetBytes(); Log.Info($"Sent {data.Length} bytes of data for DysonSphereData (INDEX: {packet.StarIndex})"); conn.SendPacket(new DysonSphereData(packet.StarIndex, data, DysonSphereRespondEvent.Load)); Multiplayer.Session.DysonSpheres.RegisterPlayer(conn, packet.StarIndex); } break; case DysonSphereRequestEvent.Unload: Multiplayer.Session.DysonSpheres.UnRegisterPlayer(conn, packet.StarIndex); break; } }
public TrashSystemNewTrashCreatedPacket(int trashId, TrashObject trashObj, TrashData trashData, ushort playerId, int localPlanetId) { TrashId = trashId; using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { trashObj.Export(writer.BinaryWriter); TrashObjectByte = writer.CloseAndGetBytes(); } using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { trashData.Export(writer.BinaryWriter); TrashDataByte = writer.CloseAndGetBytes(); } // Fix overflow in TrashObj.Export() for item.count Count = trashObj.count; LocalPlanetId = localPlanetId; PlayerId = playerId; }
private static byte[] PlanetCompute(int planetId) { PlanetData planet = GameMain.galaxy.PlanetById(planetId); HighStopwatch highStopwatch = new HighStopwatch(); highStopwatch.Begin(); // NOTE: The following has been picked-n-mixed from "PlanetModelingManager.PlanetComputeThreadMain()" // This method is **costly** - do not run it more than is required! // It generates the planet on the host and then sends it to the client PlanetAlgorithm planetAlgorithm = PlanetModelingManager.Algorithm(planet); if (planet.data == null) { planet.data = new PlanetRawData(planet.precision); planet.modData = planet.data.InitModData(planet.modData); planet.data.CalcVerts(); planet.aux = new PlanetAuxData(planet); planetAlgorithm.GenerateTerrain(planet.mod_x, planet.mod_y); planetAlgorithm.CalcWaterPercent(); //Load planet meshes and register callback to unload unneccessary stuff planet.wanted = true; planet.onLoaded += OnActivePlanetLoaded; PlanetModelingManager.modPlanetReqList.Enqueue(planet); if (planet.type != EPlanetType.Gas) { planetAlgorithm.GenerateVegetables(); planetAlgorithm.GenerateVeins(false); } } byte[] data; using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { planet.ExportRuntime(writer.BinaryWriter); data = writer.CloseAndGetBytes(); } Log.Info($"Returning terrain for {planet.name} (id:{planet.id} time:{highStopwatch.duration:F4}s)"); return data; }
public void ProcessPacket(StatisticsRequestEvent packet, NebulaConnection conn) { Player player = playerManager.GetPlayer(conn); if (player != null) { if (packet.Event == StatisticEvent.WindowOpened) { StatisticsManager.instance.RegisterPlayer(conn, player.Id); using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { StatisticsManager.ExportAllData(writer.BinaryWriter); conn.SendPacket(new StatisticsDataPacket(writer.CloseAndGetBytes())); } } else if (packet.Event == StatisticEvent.WindowClosed) { StatisticsManager.instance.UnRegisterPlayer(player.Id); } } }
public LobbyRequest(byte[] clientCert, string username, Float4[] mechaColors) { Username = username; MechaColors = mechaColors; using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { int count = 0; foreach (System.Collections.Generic.KeyValuePair <string, BepInEx.PluginInfo> pluginInfo in BepInEx.Bootstrap.Chainloader.PluginInfos) { if (pluginInfo.Value.Instance is IMultiplayerMod mod) { writer.BinaryWriter.Write(pluginInfo.Key); writer.BinaryWriter.Write(mod.Version); count++; } else { foreach (BepInEx.BepInDependency dependency in pluginInfo.Value.Dependencies) { if (dependency.DependencyGUID == NebulaModAPI.API_GUID) { writer.BinaryWriter.Write(pluginInfo.Key); writer.BinaryWriter.Write(pluginInfo.Value.Metadata.Version.ToString()); count++; } } } } ModsVersion = writer.CloseAndGetBytes(); ModsCount = count; } GameVersionSig = GameConfig.gameVersion.sig; ClientCert = clientCert; }
public override void ProcessPacket(StorageSyncRequestPacket packet, NebulaConnection conn) { if (IsClient) { return; } if (GameMain.galaxy.PlanetById(packet.PlanetId) != null) { StorageComponent storageComponent = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.factoryStorage?.storagePool[packet.StorageId]; if (storageComponent != null) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { storageComponent.Export(writer.BinaryWriter); conn.SendPacket(new StorageSyncResponsePacket(packet.PlanetId, packet.StorageId, writer.CloseAndGetBytes())); } } } }
public override void ProcessPacket(LobbyRequest packet, NebulaConnection conn) { if (IsClient) { return; } INebulaPlayer player; using (playerManager.GetPendingPlayers(out Dictionary <INebulaConnection, INebulaPlayer> pendingPlayers)) { if (!pendingPlayers.TryGetValue(conn, out player)) { conn.Disconnect(DisconnectionReason.InvalidData); Log.Warn("WARNING: Player tried to enter lobby without being in the pending list"); return; } if (GameMain.isFullscreenPaused) { conn.Disconnect(DisconnectionReason.HostStillLoading); pendingPlayers.Remove(conn); return; } Dictionary <string, string> clientMods = new Dictionary <string, string>(); using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.ModsVersion)) { for (int i = 0; i < packet.ModsCount; i++) { string guid = reader.BinaryReader.ReadString(); string version = reader.BinaryReader.ReadString(); if (!BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey(guid)) { conn.Disconnect(DisconnectionReason.ModIsMissingOnServer, guid); pendingPlayers.Remove(conn); return; } clientMods.Add(guid, version); } } foreach (KeyValuePair <string, BepInEx.PluginInfo> pluginInfo in BepInEx.Bootstrap.Chainloader.PluginInfos) { if (pluginInfo.Value.Instance is IMultiplayerMod mod) { if (!clientMods.ContainsKey(pluginInfo.Key)) { conn.Disconnect(DisconnectionReason.ModIsMissing, pluginInfo.Key); pendingPlayers.Remove(conn); return; } string version = clientMods[pluginInfo.Key]; if (mod.CheckVersion(mod.Version, version)) { continue; } conn.Disconnect(DisconnectionReason.ModVersionMismatch, $"{pluginInfo.Key};{version};{mod.Version}"); pendingPlayers.Remove(conn); return; } else { foreach (BepInEx.BepInDependency dependency in pluginInfo.Value.Dependencies) { if (dependency.DependencyGUID == NebulaModAPI.API_GUID) { string hostVersion = pluginInfo.Value.Metadata.Version.ToString(); if (!clientMods.ContainsKey(pluginInfo.Key)) { conn.Disconnect(DisconnectionReason.ModIsMissing, pluginInfo.Key); pendingPlayers.Remove(conn); return; } if (clientMods[pluginInfo.Key] != hostVersion) { conn.Disconnect(DisconnectionReason.ModVersionMismatch, $"{pluginInfo.Key};{clientMods[pluginInfo.Key]};{hostVersion}"); pendingPlayers.Remove(conn); return; } } } } } if (packet.GameVersionSig != GameConfig.gameVersion.sig) { conn.Disconnect(DisconnectionReason.GameVersionMismatch, $"{ packet.GameVersionSig };{ GameConfig.gameVersion.sig }"); pendingPlayers.Remove(conn); return; } } bool isNewUser = false; //TODO: some validation of client cert / generating auth challenge for the client // Load old data of the client string clientCertHash = CryptoUtils.Hash(packet.ClientCert); using (playerManager.GetSavedPlayerData(out Dictionary <string, IPlayerData> savedPlayerData)) { if (savedPlayerData.TryGetValue(clientCertHash, out IPlayerData value)) { using (playerManager.GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { IPlayerData playerData = value; foreach (INebulaPlayer connectedPlayer in connectedPlayers.Values) { if (connectedPlayer.Data == playerData) { playerData = value.CreateCopyWithoutMechaData(); Log.Warn($"Copy playerData for duplicated player{playerData.PlayerId} {playerData.Username}"); } } player.LoadUserData(playerData); } } else { // store player data once he fully loaded into the game (SyncCompleteProcessor) isNewUser = true; } } // Add the username to the player data player.Data.Username = !string.IsNullOrWhiteSpace(packet.Username) ? packet.Username : $"Player {player.Id}"; // Add the Mecha Color to the player data player.Data.MechaColors = packet.MechaColors; Multiplayer.Session.NumPlayers += 1; DiscordManager.UpdateRichPresence(); // if user is known and host is ingame dont put him into lobby but let him join the game if (!isNewUser && Multiplayer.Session.IsGameLoaded) { // Remove the new player from pending list using (playerManager.GetPendingPlayers(out Dictionary <INebulaConnection, INebulaPlayer> pendingPlayers)) { pendingPlayers.Remove(conn); } // Add the new player to the list using (playerManager.GetSyncingPlayers(out Dictionary <INebulaConnection, INebulaPlayer> syncingPlayers)) { syncingPlayers.Add(conn, player); } Multiplayer.Session.World.OnPlayerJoining(player.Data.Username); NebulaModAPI.OnPlayerJoinedGame?.Invoke(player.Data); // Make sure that each player that is currently in the game receives that a new player as join so they can create its RemotePlayerCharacter PlayerJoining pdata = new PlayerJoining((PlayerData)player.Data.CreateCopyWithoutMechaData(), Multiplayer.Session.NumPlayers); // Remove inventory from mecha data using (playerManager.GetConnectedPlayers(out Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { foreach (KeyValuePair <INebulaConnection, INebulaPlayer> kvp in connectedPlayers) { kvp.Value.SendPacket(pdata); } } //Add current tech bonuses to the connecting player based on the Host's mecha ((MechaData)player.Data.Mecha).TechBonuses = new PlayerTechBonuses(GameMain.mainPlayer.mecha); using (BinaryUtils.Writer p = new BinaryUtils.Writer()) { int count = 0; foreach (KeyValuePair <string, BepInEx.PluginInfo> pluginInfo in BepInEx.Bootstrap.Chainloader.PluginInfos) { if (pluginInfo.Value.Instance is IMultiplayerModWithSettings mod) { p.BinaryWriter.Write(pluginInfo.Key); mod.Export(p.BinaryWriter); count++; } } GameDesc gameDesc = GameMain.data.gameDesc; player.SendPacket(new HandshakeResponse(gameDesc.galaxyAlgo, gameDesc.galaxySeed, gameDesc.starCount, gameDesc.resourceMultiplier, gameDesc.savedThemeIds, isNewUser, (PlayerData)player.Data, p.CloseAndGetBytes(), count, Config.Options.SyncSoil, Multiplayer.Session.NumPlayers, DiscordManager.GetPartyId())); } } else { GameDesc gameDesc = Multiplayer.Session.IsGameLoaded ? GameMain.data.gameDesc : UIRoot.instance.galaxySelect.gameDesc; using (BinaryUtils.Writer p = new BinaryUtils.Writer()) { int count = 0; foreach (KeyValuePair <string, BepInEx.PluginInfo> pluginInfo in BepInEx.Bootstrap.Chainloader.PluginInfos) { if (pluginInfo.Value.Instance is IMultiplayerModWithSettings mod) { p.BinaryWriter.Write(pluginInfo.Key); mod.Export(p.BinaryWriter); count++; } } player.SendPacket(new LobbyResponse(gameDesc.galaxyAlgo, gameDesc.galaxySeed, gameDesc.starCount, gameDesc.resourceMultiplier, gameDesc.savedThemeIds, p.CloseAndGetBytes(), count, Multiplayer.Session.NumPlayers, DiscordManager.GetPartyId())); } // Send overriden Planet and Star names player.SendPacket(new NameInputPacket(GameMain.galaxy, Multiplayer.Session.LocalPlayer.Id)); } }
public static void ApplyMechaAppearance_Postfix() { if (Multiplayer.IsActive) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.mainPlayer.mecha.appearance.Export(writer.BinaryWriter); Multiplayer.Session.Network.SendPacket(new PlayerMechaArmor(Multiplayer.Session.LocalPlayer.Id, writer.CloseAndGetBytes())); } } }
public override void ProcessPacket(SyncComplete packet, NebulaConnection conn) { if (IsHost) { INebulaPlayer player = playerManager.GetSyncingPlayer(conn); if (player == null) { Log.Warn("Received a SyncComplete packet, but no player is joining."); Multiplayer.Session.World.OnAllPlayersSyncCompleted(); return; } // store the player now, not when he enters the lobby. that would cause weird teleportations when clients reenter the lobby without ever having loaded into the game string clientCertHash = CryptoUtils.Hash(packet.ClientCert); using (playerManager.GetSavedPlayerData(out Dictionary <string, IPlayerData> savedPlayerData)) { if (!savedPlayerData.TryGetValue(clientCertHash, out IPlayerData value)) { savedPlayerData.Add(clientCertHash, player.Data); } } // Should these be locked together? int syncingCount; using (playerManager.GetSyncingPlayers(out System.Collections.Generic.Dictionary <INebulaConnection, INebulaPlayer> syncingPlayers)) { bool removed = syncingPlayers.Remove(player.Connection); syncingCount = syncingPlayers.Count; } using (playerManager.GetConnectedPlayers(out System.Collections.Generic.Dictionary <INebulaConnection, INebulaPlayer> connectedPlayers)) { if (!connectedPlayers.ContainsKey(player.Connection)) { connectedPlayers.Add(player.Connection, player); } } // Load overriden Planet and Star names player.SendPacket(new NameInputPacket(GameMain.galaxy, Multiplayer.Session.LocalPlayer.Id)); // Since the player is now connected, we can safely spawn his player model Multiplayer.Session.World.SpawnRemotePlayerModel(player.Data); if (syncingCount == 0) { IPlayerData[] inGamePlayersDatas = playerManager.GetAllPlayerDataIncludingHost(); playerManager.SendPacketToAllPlayers(new SyncComplete(inGamePlayersDatas)); // Since the host is always in the game he could already have changed his mecha armor, so send it to the new player. using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { GameMain.mainPlayer.mecha.appearance.Export(writer.BinaryWriter); player.SendPacket(new PlayerMechaArmor(Multiplayer.Session.LocalPlayer.Id, writer.CloseAndGetBytes())); } // if the client had used a custom armor we should have saved a copy of it, so send it back if (player.Data.Appearance != null) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { player.Data.Appearance.Export(writer.BinaryWriter); playerManager.SendPacketToAllPlayers(new PlayerMechaArmor(player.Id, writer.CloseAndGetBytes())); } // and load custom appearance on host side too // this is the code from PlayerMechaArmonrProcessor using (Multiplayer.Session.World.GetRemotePlayersModels(out Dictionary <ushort, RemotePlayerModel> remotePlayersModels)) { if (remotePlayersModels.TryGetValue(player.Id, out RemotePlayerModel playerModel)) { if (playerModel.MechaInstance.appearance == null) { playerModel.MechaInstance.appearance = new MechaAppearance(); playerModel.MechaInstance.appearance.Init(); } player.Data.Appearance.CopyTo(playerModel.MechaInstance.appearance); playerModel.PlayerInstance.mechaArmorModel.RefreshAllPartObjects(); playerModel.PlayerInstance.mechaArmorModel.RefreshAllBoneObjects(); playerModel.MechaInstance.appearance.NotifyAllEvents(); playerModel.PlayerInstance.mechaArmorModel._Init(playerModel.PlayerInstance); playerModel.PlayerInstance.mechaArmorModel._OnOpen(); } } } // if the client has some changes made in his mecha editor send them back for them to load if (player.Data.DIYAppearance != null) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { player.Data.DIYAppearance.Export(writer.BinaryWriter); player.SendPacket(new PlayerMechaDIYArmor(writer.CloseAndGetBytes(), player.Data.DIYItemId, player.Data.DIYItemValue)); } } // add together player sand count and tell others if we are syncing soil if (Config.Options.SyncSoil) { GameMain.mainPlayer.sandCount += player.Data.Mecha.SandCount; Multiplayer.Session.Network.SendPacket(new PlayerSandCount(GameMain.mainPlayer.sandCount)); } Multiplayer.Session.World.OnAllPlayersSyncCompleted(); } } else // IsClient { // Everyone is now connected, we can safely spawn the player model of all the other players that are currently connected foreach (NebulaModel.DataStructures.PlayerData playerData in packet.AllPlayers) { if (playerData.PlayerId != Multiplayer.Session.LocalPlayer.Id) { Multiplayer.Session.World.SpawnRemotePlayerModel(playerData); } } Multiplayer.Session.World.OnAllPlayersSyncCompleted(); } }
public void ProcessPacket(StorageSyncRequestPacket packet, NebulaConnection conn) { if (GameMain.galaxy.PlanetById(packet.PlanetId) != null) { int factoryIndex = GameMain.galaxy.PlanetById(packet.PlanetId).factoryIndex; StorageComponent storageComponent = GameMain.data.factories[factoryIndex]?.factoryStorage?.storagePool[packet.StorageId]; if (storageComponent != null) { using (BinaryUtils.Writer writer = new BinaryUtils.Writer()) { storageComponent.Export(writer.BinaryWriter); conn.SendPacket(new StorageSyncResponsePacket(factoryIndex, packet.StorageId, writer.CloseAndGetBytes())); } } } }