예제 #1
0
        static void ShowModDebugInfo()
        {
            var info = new RemoteData();

            JoinData.ReadServerData(JoinData.WriteServerData(true), info);
            for (int i = 0; i < 200; i++)
            {
                info.remoteMods.Add(info.remoteMods.Last());
            }
            info.remoteFiles.Add("rwmt.multiplayer", new ModFile()
            {
                relPath = "/Test/Test.xml"
            });
            //info.remoteFiles.Add("ludeon.rimworld", new ModFile() { relPath = "/Test/Test.xml" });

            Find.WindowStack.Add(new JoinDataWindow(info));
        }
예제 #2
0
        public void HandleJoinData(ByteReader data)
        {
            Multiplayer.session.gameName = data.ReadString();
            Multiplayer.session.playerId = data.ReadInt32();

            var remoteInfo = new RemoteData
            {
                remoteRwVersion = data.ReadString(),
                remoteMpVersion = data.ReadString(),
                remoteAddress   = Multiplayer.session.address,
                remotePort      = Multiplayer.session.port,
                remoteSteamHost = Multiplayer.session.steamHost
            };

            var defDiff  = false;
            var defsData = new ByteReader(data.ReadPrefixedBytes());

            foreach (var local in MultiplayerData.localDefInfos)
            {
                var status = (DefCheckStatus)defsData.ReadByte();
                local.Value.status = status;

                if (status != DefCheckStatus.Ok)
                {
                    defDiff = true;
                }
            }

            JoinData.ReadServerData(data.ReadPrefixedBytes(), remoteInfo);

            OnMainThread.Schedule(Complete, 0.3f);

            void Complete()
            {
                if (JoinData.CompareToLocal(remoteInfo) && !defDiff)
                {
                    StartDownloading();
                    return;
                }

                if (defDiff)
                {
                    Multiplayer.StopMultiplayer();
                }

                var connectingWindow = Find.WindowStack.WindowOfType <BaseConnectingWindow>();

                MpUI.ClearWindowStack();

                var defDiffStr = "\n\n" + MultiplayerData.localDefInfos
                                 .Where(kv => kv.Value.status != DefCheckStatus.Ok)
                                 .Take(10)
                                 .Join(kv => $"{kv.Key}: {kv.Value.status}", "\n");

                Find.WindowStack.Add(new JoinDataWindow(remoteInfo)
                {
                    connectAnywayDisabled = defDiff ? "MpMismatchDefsDiff".Translate() + defDiffStr : null,
                    connectAnywayCallback = () =>
                    {
                        Find.WindowStack.Add(connectingWindow);
                        StartDownloading();
                    }
                });

                void StartDownloading()
                {
                    connection.Send(Packets.Client_WorldRequest);
                    subState = JoiningState.Waiting;
                }
            }
        }
예제 #3
0
        public static void HostServer(ServerSettings settings, bool fromReplay, bool hadSimulation, bool asyncTime)
        {
            Log.Message($"Starting the server");

            var session = new MultiplayerSession();

            if (Multiplayer.session != null) // This is the case when hosting from a replay
            {
                session.dataSnapshot = Multiplayer.session.dataSnapshot;
            }

            Multiplayer.session = session;

            session.myFactionId         = Faction.OfPlayer.loadID;
            session.localServerSettings = settings;
            session.gameName            = settings.gameName;

            // Server already pre-inited in HostWindow
            var localServer = Multiplayer.LocalServer;

            MultiplayerServer.instance = Multiplayer.LocalServer;

            if (hadSimulation)
            {
                localServer.savedGame      = GZipStream.CompressBuffer(session.dataSnapshot.gameData);
                localServer.semiPersistent = GZipStream.CompressBuffer(session.dataSnapshot.semiPersistentData);
                localServer.mapData        = session.dataSnapshot.mapData.ToDictionary(kv => kv.Key, kv => GZipStream.CompressBuffer(kv.Value));
                localServer.mapCmds        = session.dataSnapshot.mapCmds.ToDictionary(kv => kv.Key, kv => kv.Value.Select(ScheduledCommand.Serialize).ToList());
            }

            localServer.commands.debugOnlySyncCmds = Sync.handlers.Where(h => h.debugOnly).Select(h => h.syncId).ToHashSet();
            localServer.commands.hostOnlySyncCmds  = Sync.handlers.Where(h => h.hostOnly).Select(h => h.syncId).ToHashSet();
            localServer.hostUsername  = Multiplayer.username;
            localServer.coopFactionId = Faction.OfPlayer.loadID;

            localServer.rwVersion  = VersionControl.CurrentVersionString;
            localServer.mpVersion  = MpVersion.Version;
            localServer.defInfos   = MultiplayerData.localDefInfos;
            localServer.serverData = JoinData.WriteServerData(settings.syncConfigs);

            if (settings.steam)
            {
                localServer.TickEvent += SteamIntegration.ServerSteamNetTick;
            }

            if (fromReplay)
            {
                localServer.gameTimer = TickPatch.Timer;
            }

            if (!fromReplay)
            {
                SetupGameFromSingleplayer();
            }

            foreach (var tickable in TickPatch.AllTickables)
            {
                tickable.Cmds.Clear();
            }

            Find.PlaySettings.usePlanetDayNightSystem = false;

            Multiplayer.RealPlayerFaction = Faction.OfPlayer;
            localServer.playerFactions[Multiplayer.username] = Faction.OfPlayer.loadID;

            SetupLocalClient();

            Find.MainTabsRoot.EscapeCurrentTab(false);

            Multiplayer.session.AddMsg("If you are having any issues with the mod and would like some help resolving them, then please reach out to us on our Discord server:", false);
            Multiplayer.session.AddMsg(new ChatMsg_Url("https://discord.gg/S4bxXpv"), false);

            if (hadSimulation)
            {
                StartServerThread();
            }
            else
            {
                Multiplayer.WorldComp.TimeSpeed = TimeSpeed.Paused;
                foreach (var map in Find.Maps)
                {
                    map.AsyncTime().TimeSpeed = TimeSpeed.Paused;
                }

                Multiplayer.WorldComp.UpdateTimeSpeed();

                Multiplayer.GameComp.asyncTime       = asyncTime;
                Multiplayer.GameComp.debugMode       = settings.debugMode;
                Multiplayer.GameComp.logDesyncTraces = settings.desyncTraces;

                LongEventHandler.QueueLongEvent(() =>
                {
                    Multiplayer.session.dataSnapshot = SaveLoad.CreateGameDataSnapshot(SaveLoad.SaveAndReload());
                    SaveLoad.SendGameData(Multiplayer.session.dataSnapshot, false);

                    StartServerThread();
                }, "MpSaving", false, null);
            }

            void StartServerThread()
            {
                localServer.running = true;

                Multiplayer.LocalServer.serverThread = new Thread(localServer.Run)
                {
                    Name = "Local server thread"
                };
                Multiplayer.LocalServer.serverThread.Start();

                const string text = "Server started.";

                Messages.Message(text, MessageTypeDefOf.SilentInput, false);
                Log.Message(text);
            }
        }
예제 #4
0
        static MultiplayerStatic()
        {
            Native.InitLmfPtr();

            // UnityEngine.Debug.Log instead of Verse.Log.Message because the server runs on its own thread
            ServerLog.info  = str => UnityEngine.Debug.Log($"MpServerLog: {str}");
            ServerLog.error = str => UnityEngine.Debug.Log($"MpServerLog Error: {str}");
            NetDebug.Logger = new ServerLog();

            SetUsername();

            if (SteamManager.Initialized)
            {
                SteamIntegration.InitCallbacks();
            }

            Log.Message($"Multiplayer version {MpVersion.Version}");
            Log.Message($"Player's username: {Multiplayer.username}");

            var persistentObj = new GameObject();

            persistentObj.AddComponent <OnMainThread>();
            UnityEngine.Object.DontDestroyOnLoad(persistentObj);

            MpConnectionState.SetImplementation(ConnectionStateEnum.ClientSteam, typeof(ClientSteamState));
            MpConnectionState.SetImplementation(ConnectionStateEnum.ClientJoining, typeof(ClientJoiningState));
            MpConnectionState.SetImplementation(ConnectionStateEnum.ClientPlaying, typeof(ClientPlayingState));

            MultiplayerData.CollectCursorIcons();

            PersistentDialog.BindAll(typeof(Multiplayer).Assembly);

            using (DeepProfilerWrapper.Section("Multiplayer MpPatches"))
                Multiplayer.harmony.DoAllMpPatches();

            using (DeepProfilerWrapper.Section("Multiplayer patches"))
                DoPatches();

            Log.messageQueue.maxMessages = 1000;

            DoubleLongEvent(() =>
            {
                MultiplayerData.CollectDefInfos();
                Sync.PostInitHandlers();
            }, "Loading"); // Right before the events from HandleCommandLine

            HandleRestartConnect();
            HandleCommandLine();

            if (Multiplayer.arbiterInstance)
            {
                RuntimeHelpers.RunClassConstructor(typeof(Text).TypeHandle);
            }

            using (DeepProfilerWrapper.Section("Multiplayer TakeModDataSnapshot"))
                JoinData.TakeModDataSnapshot();

            using (DeepProfilerWrapper.Section("MultiplayerData PrecacheMods"))
                MultiplayerData.PrecacheMods();

            if (GenCommandLine.CommandLineArgPassed("profiler"))
            {
                SimpleProfiler.Print("mp_prof_out.txt");
            }
        }