예제 #1
0
        public void ProcessPacket(PlanetDataResponse packet, NebulaConnection conn)
        {
            // We have to track the offset we are currently at in the flattened jagged array as we decode
            int currentOffset = 0;

            for (int i = 0; i < packet.PlanetDataIDs.Length; i++)
            {
                PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetDataIDs[i]);

                Log.Info($"Parsing {packet.PlanetDataBytesLengths[i]} bytes of data for planet {planet.name} (ID: {planet.id})");
                byte[] planetData = packet.PlanetDataBytes.Skip(currentOffset).Take(packet.PlanetDataBytesLengths[i]).ToArray();

                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(planetData))
                {
                    planet.ImportRuntime(reader.BinaryReader);
                }

                lock (PlanetModelingManager.genPlanetReqList)
                {
                    PlanetModelingManager.genPlanetReqList.Enqueue(planet);
                }

                currentOffset += packet.PlanetDataBytesLengths[i];
            }
        }
예제 #2
0
 public override void ProcessPacket(StatisticsDataPacket packet, NebulaConnection conn)
 {
     using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.StatisticsBinaryData))
     {
         Multiplayer.Session.Statistics.ImportAllData(reader.BinaryReader);
     }
 }
        public void ProcessPacket(StorageSyncResponsePacket packet, NebulaConnection conn)
        {
            StorageComponent storageComponent = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.factoryStorage?.storagePool[packet.StorageIndex];

            if (storageComponent != null)
            {
                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.StorageComponent))
                {
                    storageComponent.Import(reader.BinaryReader);
                }
                ItemProto itemProto = LDB.items.Select((int)GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.entityPool[storageComponent.entityId].protoId);

                //Imitation of UIStorageWindow.OnStorageIdChange()
                StorageManager.ActiveWindowTitle.text = itemProto.name;
                StorageManager.ActiveUIStorageGrid._Free();
                StorageManager.ActiveUIStorageGrid._Init(storageComponent);
                StorageManager.ActiveStorageComponent = storageComponent;
                MethodInvoker.GetHandler(AccessTools.Method(typeof(UIStorageGrid), "SetStorageData")).Invoke(StorageManager.ActiveUIStorageGrid, StorageManager.ActiveStorageComponent);
                StorageManager.ActiveUIStorageGrid._Open();
                StorageManager.ActiveUIStorageGrid.OnStorageDataChanged();
                StorageManager.ActiveBansSlider.maxValue = (float)storageComponent.size;
                StorageManager.ActiveBansSlider.value    = (float)(storageComponent.size - storageComponent.bans);
                StorageManager.ActiveBansValueText.text  = StorageManager.ActiveBansSlider.value.ToString();
                GameMain.galaxy.PlanetById(packet.PlanetId).factory.factoryStorage.storagePool[packet.StorageIndex] = storageComponent;
            }
        }
예제 #4
0
        public override void ProcessPacket(DysonSphereData packet, NebulaConnection conn)
        {
            if (IsHost)
            {
                return;
            }

            //Failsafe, if client does not have instantiated sphere for the star, it will create dummy one that will be replaced during import
            if (GameMain.data.dysonSpheres[packet.StarIndex] == null)
            {
                GameMain.data.dysonSpheres[packet.StarIndex] = new DysonSphere();
                GameMain.data.statistics.production.Init(GameMain.data);
                //Another failsafe, DysonSphere import requires initialized factory statistics
                if (GameMain.data.statistics.production.factoryStatPool[0] == null)
                {
                    GameMain.data.statistics.production.factoryStatPool[0] = new FactoryProductionStat();
                    GameMain.data.statistics.production.factoryStatPool[0].Init();
                }
                GameMain.data.dysonSpheres[packet.StarIndex].Init(GameMain.data, GameMain.data.galaxy.stars[packet.StarIndex]);
            }

            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.BinaryData))
            {
                GameMain.data.dysonSpheres[packet.StarIndex].Import(reader.BinaryReader);
            }
        }
예제 #5
0
 public override void ProcessPacket(StatisticsDataPacket packet, NebulaConnection conn)
 {
     using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.StatisticsBinaryData))
     {
         StatisticsManager.ImporAllHistorytData(reader.BinaryReader);
     }
 }
예제 #6
0
 public void ProcessPacket(TrashSystemResponseDataPacket packet, NebulaConnection conn)
 {
     using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.TrashSystemData))
     {
         GameMain.data.trashSystem.Import(reader.BinaryReader);
     }
 }
예제 #7
0
        public override void ProcessPacket(HandshakeResponse packet, NebulaConnection conn)
        {
            using (BinaryUtils.Reader p = new BinaryUtils.Reader(packet.ModsSettings))
            {
                for (int i = 0; i < packet.ModsSettingsCount; i++)
                {
                    string     guid = p.BinaryReader.ReadString();
                    PluginInfo info = Chainloader.PluginInfos[guid];
                    if (info.Instance is IMultiplayerModWithSettings mod)
                    {
                        mod.Import(p.BinaryReader);
                    }
                }
            }

            // overwrite local setting with host setting, but dont save it as its a temp setting for this session
            Config.Options.SyncSoil = packet.SyncSoil;

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = false;
            ((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(packet.LocalPlayerData, packet.IsNewPlayer);

            Multiplayer.Session.IsInLobby      = false;
            Multiplayer.ShouldReturnToJoinMenu = false;

            GameDesc gameDesc = new GameDesc();

            gameDesc.SetForNewGame(packet.AlgoVersion, packet.GalaxySeed, packet.StarCount, 1, packet.ResourceMultiplier);
            DSPGame.StartGameSkipPrologue(gameDesc);

            InGamePopup.ShowInfo("Loading", "Loading state from server, please wait", null);
        }
예제 #8
0
        public override void ProcessPacket(LobbyResponse packet, NebulaConnection conn)
        {
            using (BinaryUtils.Reader p = new BinaryUtils.Reader(packet.ModsSettings))
            {
                for (int i = 0; i < packet.ModsSettingsCount; i++)
                {
                    string     guid = p.BinaryReader.ReadString();
                    PluginInfo info = Chainloader.PluginInfos[guid];
                    if (info.Instance is IMultiplayerModWithSettings mod)
                    {
                        mod.Import(p.BinaryReader);
                    }
                }
            }
            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = false;
            Multiplayer.Session.NumPlayers = packet.NumPlayers;
            Multiplayer.Session.IsInLobby  = true;
            DiscordManager.UpdateRichPresence(partyId: packet.DiscordPartyId);

            UIRoot.instance.galaxySelect._Open();
            UIRoot.instance.uiMainMenu._Close();

            GameDesc gameDesc = new GameDesc();

            gameDesc.SetForNewGame(packet.GalaxyAlgo, packet.GalaxySeed, packet.StarCount, 1, packet.ResourceMultiplier);
            gameDesc.savedThemeIds = packet.SavedThemeIds;

            UIRoot.instance.galaxySelect.gameDesc = gameDesc;
            UIRoot.instance.galaxySelect.SetStarmapGalaxy();
        }
예제 #9
0
        public override void ProcessPacket(StorageSyncResponsePacket packet, NebulaConnection conn)
        {
            if (IsHost)
            {
                return;
            }

            StorageComponent storageComponent = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.factoryStorage?.storagePool[packet.StorageIndex];

            if (storageComponent != null)
            {
                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.StorageComponent))
                {
                    storageComponent.Import(reader.BinaryReader);
                }
                ItemProto itemProto = LDB.items.Select((int)GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.entityPool[storageComponent.entityId].protoId);

                //Imitation of UIStorageWindow.OnStorageIdChange()
                Multiplayer.Session.Storage.ActiveWindowTitle.text = itemProto.name;
                Multiplayer.Session.Storage.ActiveUIStorageGrid._Free();
                Multiplayer.Session.Storage.ActiveUIStorageGrid._Init(storageComponent);
                Multiplayer.Session.Storage.ActiveStorageComponent = storageComponent;
                Multiplayer.Session.Storage.ActiveUIStorageGrid.SetStorageData(Multiplayer.Session.Storage.ActiveStorageComponent);
                Multiplayer.Session.Storage.ActiveUIStorageGrid._Open();
                Multiplayer.Session.Storage.ActiveUIStorageGrid.OnStorageDataChanged();
                Multiplayer.Session.Storage.ActiveBansSlider.maxValue = storageComponent.size;
                Multiplayer.Session.Storage.ActiveBansSlider.value    = storageComponent.size - storageComponent.bans;
                Multiplayer.Session.Storage.ActiveBansValueText.text  = Multiplayer.Session.Storage.ActiveBansSlider.value.ToString();
                GameMain.galaxy.PlanetById(packet.PlanetId).factory.factoryStorage.storagePool[packet.StorageIndex] = storageComponent;
            }
        }
예제 #10
0
 public static void GS2ApplySettings(byte[] compressedSettings)
 {
     using (BinaryUtils.Reader reader = new BinaryUtils.Reader(compressedSettings))
     {
         GS2_GSSettings.GetMethod("DeSerialize").Invoke(GS2_GSSettings.GetProperty("Instance"), new object[] { reader.BinaryReader.ReadString() });
     }
 }
예제 #11
0
 public override void ProcessPacket(WarningDataPacket packet, NebulaConnection conn)
 {
     Multiplayer.Session.Warning.TickData = packet.Tick;
     using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.BinaryData))
     {
         Multiplayer.Session.Warning.ImportBinaryData(reader.BinaryReader, packet.ActiveWarningCount);
     }
 }
 public TrashData GetTrashData()
 {
     using (BinaryUtils.Reader reader = new BinaryUtils.Reader(TrashDataByte))
     {
         TrashData result = new TrashData();
         result.Import(reader.BinaryReader);
         return(result);
     }
 }
예제 #13
0
        public PrebuildData GetPrebuildData()
        {
            PrebuildData prebuild = new PrebuildData();

            using (BinaryUtils.Reader writer = new BinaryUtils.Reader(PrebuildDataRaw))
            {
                prebuild.Import(writer.BinaryReader);
            }
            return(prebuild);
        }
 public TrashObject GetTrashObject()
 {
     using (BinaryUtils.Reader reader = new BinaryUtils.Reader(TrashObjectByte))
     {
         TrashObject result = new TrashObject();
         result.Import(reader.BinaryReader);
         result.count = Count;
         return(result);
     }
 }
예제 #15
0
        public void ProcessPacket(GameHistoryDataResponse packet, NebulaConnection conn)
        {
            //Reset all current values
            GameMain.data.history.Init(GameMain.data);

            Log.Info($"Parsing History data from the server.");
            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.HistoryBinaryData))
            {
                GameMain.data.history.Import(reader.BinaryReader);
            }
        }
        public void ProcessPacket(StatisticUpdateDataPacket packet, NebulaConnection conn)
        {
            StatisticalSnapShot snapshot;

            using (StatisticsManager.IsIncomingRequest.On())
            {
                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.StatisticsBinaryData))
                {
                    ref FactoryProductionStat[] productionStats = ref GameMain.statistics.production.factoryStatPool;
                    int numOfSnapshots = reader.BinaryReader.ReadInt32();
                    for (int i = 0; i < numOfSnapshots; i++)
                    {
                        //Clear all current statistical data
                        for (int a = 0; a < GameMain.statistics.production.factoryStatPool.Length; a++)
                        {
                            GameMain.statistics.production.factoryStatPool[a]?.ClearRegisters();
                        }

                        //Load new snapshot
                        snapshot = new StatisticalSnapShot(reader.BinaryReader);
                        for (int factoryId = 0; factoryId < snapshot.ProductionChangesPerFactory.Length; factoryId++)
                        {
                            if (productionStats[factoryId] == null)
                            {
                                productionStats[factoryId] = new FactoryProductionStat();
                                productionStats[factoryId].Init();
                            }
                            for (int changeId = 0; changeId < snapshot.ProductionChangesPerFactory[factoryId].Count; changeId++)
                            {
                                if (snapshot.ProductionChangesPerFactory[factoryId][changeId].IsProduction)
                                {
                                    productionStats[factoryId].productRegister[snapshot.ProductionChangesPerFactory[factoryId][changeId].ProductId] += snapshot.ProductionChangesPerFactory[factoryId][changeId].Amount;
                                }
                                else
                                {
                                    productionStats[factoryId].consumeRegister[snapshot.ProductionChangesPerFactory[factoryId][changeId].ProductId] += snapshot.ProductionChangesPerFactory[factoryId][changeId].Amount;
                                }
                            }
                            //Import power system statistics
                            productionStats[factoryId].powerGenRegister = snapshot.PowerGenerationRegister[factoryId];
                            productionStats[factoryId].powerConRegister = snapshot.PowerConsumptionRegister[factoryId];
                            productionStats[factoryId].powerChaRegister = snapshot.PowerChargingRegister[factoryId];
                            productionStats[factoryId].powerDisRegister = snapshot.PowerDischargingRegister[factoryId];

                            //Import fake energy stored values
                            StatisticsManager.PowerEnergyStoredData = snapshot.EnergyStored;

                            //Import Research statistics
                            productionStats[factoryId].hashRegister = snapshot.HashRegister[factoryId];
                        }
                        GameMain.statistics.production.GameTick(snapshot.CapturedGameTick);
                    }
                }
            }
        public override void ProcessPacket(MilestoneDataResponse packet, NebulaConnection conn)
        {
            if (IsHost)
            {
                return;
            }

            //Reset all current values
            GameMain.data.milestoneSystem.Init(GameMain.data);

            Log.Info($"Parsing Milstone data from the server.");
            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.BinaryData))
            {
                GameMain.data.milestoneSystem.Import(reader.BinaryReader);
            }
        }
예제 #18
0
        public static bool GetOrCreateFactory_Prefix(GameData __instance, PlanetFactory __result, PlanetData planet)
        {
            // We want the original method to run on the host client or in single player games
            if (!SimulatedWorld.Initialized || LocalPlayer.IsMasterClient)
            {
                return(true);
            }

            // Get the recieved bytes from the remote server that we will import
            byte[] factoryBytes;
            if (!LocalPlayer.PendingFactories.TryGetValue(planet.id, out factoryBytes))
            {
                // We messed up, just defer to the default behaviour on the client (will cause desync but not outright crash)
                Log.Error($"PendingFactories did not have value we wanted, factory will not be synced!");
                return(true);
            }

            // Take it off the list, as we will process it now
            LocalPlayer.PendingFactories.Remove(planet.id);

            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(factoryBytes))
            {
                GameMain.data.factoryCount = reader.BinaryReader.ReadInt32();
                int factoryIndex = reader.BinaryReader.ReadInt32();
                // Import the factory from the given bytes, which will have been gotten or created on the host by the original function
                __instance.factories[factoryIndex] = new PlanetFactory();

                if (planet.factory == null)
                {
                    __instance.factories[factoryIndex].Import(factoryIndex, __instance, reader.BinaryReader);
                    planet.factory      = __instance.factories[factoryIndex];
                    planet.factoryIndex = factoryIndex;
                }
                else
                {
                    __instance.factories[planet.factoryIndex].Import(planet.factoryIndex, __instance, reader.BinaryReader);
                    planet.factory = __instance.factories[planet.factoryIndex];
                }
            }

            // Assign the factory to the result
            __result = __instance.factories[planet.factoryIndex];

            // Do not run the original method
            return(false);
        }
예제 #19
0
        public List <BuildPreview> GetBuildPreviews()
        {
            List <BuildPreview> result = new List <BuildPreview>();

            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(BuildPreviewData))
            {
                int previewCount = reader.BinaryReader.ReadInt32();
                for (int i = 0; i < previewCount; i++)
                {
                    result.Add(new BuildPreview());
                }
                for (int i = 0; i < previewCount; i++)
                {
                    DeserializeBuildPreview(result[i], result, reader.BinaryReader);
                }
            }
            return(result);
        }
예제 #20
0
        public override void ProcessPacket(PlanetDataResponse packet, NebulaConnection conn)
        {
            if (IsHost)
            {
                return;
            }


            PlanetData planet = null;

            if (Multiplayer.Session.IsInLobby)
            {
                planet = UIRoot.instance.galaxySelect.starmap._galaxyData.PlanetById(packet.PlanetDataID);
            }
            else
            {
                planet = GameMain.galaxy.PlanetById(packet.PlanetDataID);
            }

            Log.Info($"Parsing {packet.PlanetDataByte.Length} bytes of data for planet {planet.name} (ID: {planet.id})");

            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.PlanetDataByte))
            {
                planet.ImportRuntime(reader.BinaryReader);
            }

            if (Multiplayer.Session.IsInLobby)
            {
                // Pretend planet is loaded to make planetDetail show resources
                planet.loaded = true;
                UIRoot.instance.uiGame.planetDetail.RefreshDynamicProperties();
            }
            else
            {
                lock (PlanetModelingManager.genPlanetReqList)
                {
                    PlanetModelingManager.genPlanetReqList.Enqueue(planet);
                }
            }
        }
예제 #21
0
        public void ProcessPacket(DysonSphereData packet, NebulaConnection conn)
        {
            //Failsafe, if client does not have instantiated sphere for the star, it will create dummy one that will be replaced during import
            if (GameMain.data.dysonSpheres[packet.StarIndex] == null)
            {
                GameMain.data.dysonSpheres[packet.StarIndex] = new DysonSphere();
                GameMain.data.statistics.production.Init(GameMain.data);
                //Another failsafe, DysonSphere import requires initialized factory statistics
                if (GameMain.data.statistics.production.factoryStatPool[0] == null)
                {
                    GameMain.data.statistics.production.factoryStatPool[0] = new FactoryProductionStat();
                    GameMain.data.statistics.production.factoryStatPool[0].Init();
                }
                GameMain.data.dysonSpheres[packet.StarIndex].Init(GameMain.data, GameMain.data.galaxy.stars[packet.StarIndex]);
            }

            //Log.Info($"Parsing {packet.BinaryData.Length} bytes of data for DysonSphere in system {GameMain.data.galaxy.stars[packet.StarIndex].name} (Index: {GameMain.data.galaxy.stars[packet.StarIndex].index})");
            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.BinaryData))
            {
                GameMain.data.dysonSpheres[packet.StarIndex].Import(reader.BinaryReader);
            }
        }
예제 #22
0
        public override void ProcessPacket(DysonSphereData packet, NebulaConnection conn)
        {
            if (IsHost)
            {
                return;
            }

            switch (packet.Event)
            {
            case DysonSphereRespondEvent.List:
                //Overwrite content assigned by UIDETopFunction.SetDysonComboBox()
                UIComboBox dysonBox = UIRoot.instance.uiGame.dysonEditor.controlPanel.topFunction.dysonBox;
                using (BinaryReader br = new BinaryUtils.Reader(packet.BinaryData).BinaryReader)
                {
                    dysonBox.Items     = new List <string>();
                    dysonBox.ItemsData = new List <int>();
                    int count = br.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        int starIndex = br.ReadInt32();
                        dysonBox.Items.Add(GameMain.galaxy.stars[starIndex].displayName);
                        dysonBox.ItemsData.Add(starIndex);
                    }
                }
                int index = dysonBox.ItemsData.FindIndex(x => x == UIRoot.instance.uiGame.dysonEditor.selection.viewStar?.index);
                dysonBox.itemIndex = index >= 0 ? index : 0;
                break;

            case DysonSphereRespondEvent.Load:
                //Failsafe, if client does not have instantiated sphere for the star, it will create dummy one that will be replaced during import
                GameMain.data.dysonSpheres[packet.StarIndex] = new DysonSphere();
                GameMain.data.statistics.production.Init(GameMain.data);
                //Another failsafe, DysonSphere import requires initialized factory statistics
                if (GameMain.data.statistics.production.factoryStatPool[0] == null)
                {
                    GameMain.data.statistics.production.factoryStatPool[0] = new FactoryProductionStat();
                    GameMain.data.statistics.production.factoryStatPool[0].Init();
                }
                GameMain.data.dysonSpheres[packet.StarIndex].Init(GameMain.data, GameMain.data.galaxy.stars[packet.StarIndex]);

                StarData star = GameMain.galaxy.stars[packet.StarIndex];
                Log.Info($"Parsing {packet.BinaryData.Length} bytes of data for DysonSphere {star.name} (INDEX: {star.id})");
                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.BinaryData))
                {
                    GameMain.data.dysonSpheres[packet.StarIndex].Import(reader.BinaryReader);
                }
                if (UIRoot.instance.uiGame.dysonEditor.active)
                {
                    UIRoot.instance.uiGame.dysonEditor.selection.SetViewStar(GameMain.galaxy.stars[packet.StarIndex]);
                    UIComboBox dysonBox2 = UIRoot.instance.uiGame.dysonEditor.controlPanel.topFunction.dysonBox;
                    int        index2    = dysonBox2.ItemsData.FindIndex(x => x == UIRoot.instance.uiGame.dysonEditor.selection.viewStar?.index);
                    dysonBox2.itemIndex = index2 >= 0 ? index2 : 0;
                }
                if (Multiplayer.Session.IsGameLoaded)
                {
                    // Don't fade out when client is still joining
                    InGamePopup.FadeOut();
                }
                Multiplayer.Session.DysonSpheres.RequestingIndex = -1;
                Multiplayer.Session.DysonSpheres.IsNormal        = true;
                break;

            case DysonSphereRespondEvent.Desync:
                Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, conn);
                break;
            }
        }
예제 #23
0
        public override void ProcessPacket(StatisticUpdateDataPacket packet, NebulaConnection conn)
        {
            StatisticalSnapShot snapshot;

            using (Multiplayer.Session.Statistics.IsIncomingRequest.On())
            {
                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.StatisticsBinaryData))
                {
                    bool itemChanged = false;
                    ref  FactoryProductionStat[] productionStats = ref GameMain.statistics.production.factoryStatPool;
                    int  numOfSnapshots = reader.BinaryReader.ReadInt32();
                    for (int i = 0; i < numOfSnapshots; i++)
                    {
                        //Load new snapshot
                        snapshot = new StatisticalSnapShot(reader.BinaryReader);
                        for (int factoryId = 0; factoryId < snapshot.ProductionChangesPerFactory.Length; factoryId++)
                        {
                            if (productionStats[factoryId] == null)
                            {
                                productionStats[factoryId] = new FactoryProductionStat();
                                productionStats[factoryId].Init();
                            }
                            //Clear current statistical data
                            productionStats[factoryId].PrepareTick();

                            for (int changeId = 0; changeId < snapshot.ProductionChangesPerFactory[factoryId].Count; changeId++)
                            {
                                StatisticalSnapShot.ProductionChangeStruct productionChange = snapshot.ProductionChangesPerFactory[factoryId][changeId];
                                if (productionChange.IsProduction)
                                {
                                    productionStats[factoryId].productRegister[productionChange.ProductId] += productionChange.Amount;
                                }
                                else
                                {
                                    productionStats[factoryId].consumeRegister[productionChange.ProductId] += productionChange.Amount;
                                }
                            }
                            //Import power system statistics
                            productionStats[factoryId].powerGenRegister = snapshot.PowerGenerationRegister[factoryId];
                            productionStats[factoryId].powerConRegister = snapshot.PowerConsumptionRegister[factoryId];
                            productionStats[factoryId].powerChaRegister = snapshot.PowerChargingRegister[factoryId];
                            productionStats[factoryId].powerDisRegister = snapshot.PowerDischargingRegister[factoryId];

                            //Import fake energy stored values
                            Multiplayer.Session.Statistics.PowerEnergyStoredData = snapshot.EnergyStored;

                            //Import Research statistics
                            productionStats[factoryId].hashRegister = snapshot.HashRegister[factoryId];

                            //Processs changed registers. FactoryProductionStat.AfterTick() is empty currently so we ignore it.
                            productionStats[factoryId].GameTick(snapshot.CapturedGameTick);
                            itemChanged |= productionStats[factoryId].itemChanged;
                        }
                    }
                    //Trigger GameMain.statistics.production.onItemChange() event when itemChanged is true
                    if (itemChanged)
                    {
                        UIRoot.instance.uiGame.statWindow.OnItemChange();
                        NebulaModel.Logger.Log.Debug("StatisticsUpdateProcessor: itemChanged");
                    }
                }
            }
예제 #24
0
        public override void ProcessPacket(PlayerMechaArmor packet, NebulaConnection conn)
        {
            INebulaPlayer player = null;

            if (IsHost)
            {
                // broadcast to other players
                player = playerManager.GetPlayer(conn);
                if (player != null)
                {
                    playerManager.SendPacketToOtherPlayers(packet, player);
                }
            }

            using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.AppearanceData))
            {
                if (Multiplayer.Session.LocalPlayer.Id == packet.PlayerId)
                {
                    GameMain.mainPlayer.mecha.appearance.Import(reader.BinaryReader);
                    GameMain.mainPlayer.mechaArmorModel.RefreshAllPartObjects();
                    GameMain.mainPlayer.mechaArmorModel.RefreshAllBoneObjects();
                    GameMain.mainPlayer.mecha.appearance.NotifyAllEvents();
                    GameMain.mainPlayer.mechaArmorModel._Init(GameMain.mainPlayer);
                    GameMain.mainPlayer.mechaArmorModel._OnOpen();

                    // and also load it in the mecha editor
                    UIMechaEditor editor = UIRoot.instance.uiMechaEditor;
                    if (editor != null)
                    {
                        editor.selection.ClearSelection();
                        editor.saveGroup._Close();
                        if (editor.mecha.diyAppearance == null)
                        {
                            editor.mecha.diyAppearance = new MechaAppearance();
                            editor.mecha.diyAppearance.Init();
                        }
                        GameMain.mainPlayer.mecha.appearance.CopyTo(editor.mecha.diyAppearance);
                        editor.mechaArmorModel.RefreshAllPartObjects();
                        editor.mechaArmorModel.RefreshAllBoneObjects();
                        editor.mecha.diyAppearance.NotifyAllEvents();
                        editor._left_content_height_max = 0f;
                        editor.SetLeftScrollTop();
                        editor.saveGroup._Open();
                    }
                }
                else
                {
                    using (Multiplayer.Session.World.GetRemotePlayersModels(out Dictionary <ushort, RemotePlayerModel> remotePlayersModels))
                    {
                        if (remotePlayersModels.TryGetValue(packet.PlayerId, out RemotePlayerModel playerModel))
                        {
                            playerModel.MechaInstance.appearance.Import(reader.BinaryReader);
                            playerModel.PlayerInstance.mechaArmorModel.RefreshAllPartObjects();
                            playerModel.PlayerInstance.mechaArmorModel.RefreshAllBoneObjects();
                            playerModel.MechaInstance.appearance.NotifyAllEvents();
                            playerModel.PlayerInstance.mechaArmorModel._Init(playerModel.PlayerInstance);
                            playerModel.PlayerInstance.mechaArmorModel._OnOpen();

                            // and store the appearance on the server
                            if (IsHost && player != null)
                            {
                                if (player.Data.Appearance == null)
                                {
                                    player.Data.Appearance = new MechaAppearance();
                                    player.Data.Appearance.Init();
                                }
                                playerModel.MechaInstance.appearance.CopyTo(player.Data.Appearance);
                            }
                        }
                    }
                }
            }
        }
예제 #25
0
        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));
            }
        }
예제 #26
0
        public override void ProcessPacket(PlayerMechaDIYArmor packet, NebulaConnection conn)
        {
            // store DIYAppearance and items to serve them when player connects again
            if (IsHost)
            {
                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.DIYAppearanceData))
                {
                    INebulaPlayer player = playerManager.GetPlayer(conn);
                    if (player != null)
                    {
                        if (player.Data.DIYAppearance == null)
                        {
                            player.Data.DIYAppearance = new MechaAppearance();
                            player.Data.DIYAppearance.Init();
                        }
                        player.Data.DIYAppearance.Import(reader.BinaryReader);

                        player.Data.DIYItemId    = packet.DIYItemId;
                        player.Data.DIYItemValue = packet.DIYItemValue;
                    }
                }
            }
            else
            {
                // load DIYAppearance received from host to display in mecha appearance editor
                using (BinaryUtils.Reader reader = new BinaryUtils.Reader(packet.DIYAppearanceData))
                {
                    Player        player = GameMain.mainPlayer;
                    UIMechaEditor editor = UIRoot.instance.uiMechaEditor;

                    if (player.mecha.diyAppearance == null)
                    {
                        player.mecha.diyAppearance = new MechaAppearance();
                        player.mecha.diyAppearance.Init();
                    }
                    player.mecha.diyAppearance.Import(reader.BinaryReader);

                    if (packet.DIYItemId.Length > 0)
                    {
                        player.mecha.diyItems.Clear();
                        for (int i = 0; i < packet.DIYItemId.Length; i++)
                        {
                            player.mecha.diyItems.items[packet.DIYItemId[i]] = packet.DIYItemValue[i];
                        }
                    }

                    if (editor != null)
                    {
                        editor.selection.ClearSelection();
                        editor.saveGroup._Close();
                        if (editor.mecha.diyAppearance == null)
                        {
                            editor.mecha.diyAppearance = new MechaAppearance();
                            editor.mecha.diyAppearance.Init();
                        }
                        GameMain.mainPlayer.mecha.diyAppearance.CopyTo(editor.mecha.diyAppearance);
                        editor.mechaArmorModel.RefreshAllPartObjects();
                        editor.mechaArmorModel.RefreshAllBoneObjects();
                        editor.mecha.diyAppearance.NotifyAllEvents();
                        editor._left_content_height_max = 0f;
                        editor.SetLeftScrollTop();
                        editor.saveGroup._Open();
                    }
                }
            }
        }