Ejemplo n.º 1
0
        public void Reset()
        {
            Profiler.LmpReferenceTime.Start();

            Debug.Log($"[LMP]: KSP installed at {KspPath}");
            Debug.Log($"[LMP]: LMP installed at {AssemblyPath}");

            if (!SettingsSystem.CurrentSettings.DisclaimerAccepted && HighLogic.LoadedScene == GameScenes.MAINMENU)
            {
                Enabled = false;
                DisclaimerWindow.Singleton.Display = true;
            }

            if (!CompatibilityChecker.IsCompatible() || !InstallChecker.IsCorrectlyInstalled())
            {
                Enabled = false;
                return;
            }

            SetupDirectoriesIfNeeded();
            UniverseSyncCache.Singleton.ExpireCache();
            NetworkMain.StartNetworkSystem();

            //Register events needed to bootstrap the workers.
            GameEvents.onHideUI.Add(() => { ShowGui = false; });
            GameEvents.onShowUI.Add(() => { ShowGui = true; });

            SystemsHandler.KillAllSystems();

            HandleCommandLineArgs();
            Debug.Log($"[LMP]: LunaMultiPlayer {VersionInfo.FullVersionNumber} Initialized!");
        }
Ejemplo n.º 2
0
        public void Reset()
        {
            _mainThreadId = Thread.CurrentThread.ManagedThreadId;

            LunaLog.Log($"[LMP]: KSP installed at {Client.KspPath}");
            LunaLog.Log($"[LMP]: LMP installed at {AssemblyPath}");

            if (!SettingsSystem.CurrentSettings.DisclaimerAccepted && HighLogic.LoadedScene == GameScenes.MAINMENU)
            {
                Enabled = false;
                DisclaimerDialog.SpawnDialog();
            }

            if (!CompatibilityChecker.IsCompatible() || !InstallChecker.IsCorrectlyInstalled())
            {
                Enabled = false;
                return;
            }

            SetupDirectoriesIfNeeded();
            UniverseSyncCache.ExpireCache();
            NetworkMain.StartNetworkSystem();

            //Register events needed to bootstrap the workers.
            GameEvents.onHideUI.Add(() => { ShowGui = false; });
            GameEvents.onShowUI.Add(() => { ShowGui = true; });

            SystemsHandler.KillAllSystems();

            HandleCommandLineArgs();
            LunaLog.Log($"[LMP]: LunaMultiPlayer {VersionInfo.FullVersionNumber} Initialized!");
            LunaLog.ProcessLogMessages();
        }
Ejemplo n.º 3
0
    void OnClick()
    {
        JObject sjson = new JObject();

        sjson["type"] = NetworkProtocol.Post_Detail;
        sjson["no"]   = json["no"];
        NetworkMain.SendMessage(sjson);
    }
Ejemplo n.º 4
0
    public void Delete()
    {
        JObject json = new JObject();

        json["type"] = NetworkProtocol.Inventory_Remove;
        json["no"]   = no;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 5
0
    public void Click()
    {
        JObject json = new JObject();

        json["type"] = NetworkProtocol.Study_SignUp;
        json["name"] = key;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 6
0
    public void ButtonClick()
    {
        JObject json = new JObject();

        json["type"] = NetworkProtocol.NewStudy;
        json["name"] = NameBox.value;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 7
0
    public void Page(int newpage)
    {
        JObject json = new JObject();

        json["type"] = NetworkProtocol.Post_Open;
        json["page"] = newpage;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 8
0
    public void SaveChatting()
    {
        JObject json = new JObject();

        json["type"] = NetworkProtocol.Study_SaveChatting;
        json["name"] = key;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 9
0
    void Start()
    {
        // 들어온 다음에 로딩 완료 메세지를 보낸다.
        JObject json = new JObject();

        json["type"] = NetworkProtocol.EnterWorld;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 10
0
    public void MoveTabSend(GameObject tab)
    {
        JObject json = new JObject();

        json["type"] = NetworkProtocol.Study_UI;
        json["tab"]  = tab.name;
        json["name"] = key;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 11
0
    public void OnClick()
    {
        JObject json = new JObject();

        json["type"]     = NetworkProtocol.Login;
        json["id"]       = ID.value;
        json["password"] = Password.value;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 12
0
    public void KeywordAddButton()
    {
        JObject json = new JObject();

        json["type"]    = NetworkProtocol.Keyword_Add;
        json["keyword"] = InputBox.value;
        NetworkMain.SendMessage(json);
        InputBox.value = "";
    }
Ejemplo n.º 13
0
    public void OnDoubleClick()
    {
        // 인벤토리로 다운로드 요청
        JObject json = new JObject();

        json["type"]       = NetworkProtocol.Study_FileDownload;
        json["group_name"] = Preset.objects.StudyWindow.key;
        json["no"]         = no;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 14
0
 // Use this for initialization
 void OnClick()
 {
     if (UICamera.currentTouchID == -2)
     {
         JObject sjson = new JObject();
         sjson["type"]    = NetworkProtocol.Keyword_Remove;
         sjson["keyword"] = label.text;
         NetworkMain.SendMessage(sjson);
     }
 }
Ejemplo n.º 15
0
    public void Accept_Button()
    {
        JObject json = new JObject();

        json["type"]     = NetworkProtocol.Study_Member_Request;
        json["name"]     = Preset.objects.StudyWindow.key;
        json["id"]       = id;
        json["positive"] = true;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 16
0
    public void ClickContent()
    {
        string url = Content_detail.GetUrlAtPosition(UICamera.lastHit.point);

        if (!string.IsNullOrEmpty(url))
        {
            JObject json = new JObject();
            json["type"]    = NetworkProtocol.GetFileInPost;
            json["post_no"] = no;
            json["file_no"] = url.Replace("file-", "");
            NetworkMain.SendMessage(json);
        }
    }
Ejemplo n.º 17
0
    public void SendPost()
    {
        JObject json = new JObject();

        json["type"]     = NetworkProtocol.SendPost;
        json["title"]    = Write_Title.value;
        json["content"]  = Write_Content.value;
        json["receiver"] = Write_Receiver.value;
        if (File_number != -1)
        {
            json["file"] = File_number;
        }
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 18
0
    void Send()
    {
        mInput.isSelected = false;
        string text = NGUIText.StripSymbols(mInput.value);

        mInput.value = "";
        if (!string.IsNullOrEmpty(text))
        {
            JObject json = new JObject();
            json["type"]    = NetworkProtocol.Chat;
            json["message"] = text;
            NetworkMain.SendMessage(json);
        }
    }
Ejemplo n.º 19
0
 void OnDoubleClick()
 {
     if (Preset.objects.PostWindow.isOpen())
     {
         Preset.objects.PostWindow.InputItem(no, UI_title.text);
     }
     else if (Preset.objects.StudyWindow.isOpen())
     {
         // 스터디에 파일 업로드
         JObject json = new JObject();
         json["type"]       = NetworkProtocol.Study_FileUpload;
         json["group_name"] = Preset.objects.StudyWindow.key;
         json["no"]         = no;
         NetworkMain.SendMessage(json);
     }
 }
Ejemplo n.º 20
0
 // Update is called once per frame
 void Update()
 {
     if (UIInput.selection == null) // 다른 UIInput에 입력중이 아닌경우
     {
         if (Input.GetKeyDown(KeyCode.F))
         {
             if (select_action != null)
             {
                 JObject json = new JObject();
                 json["type"]     = NetworkProtocol.Action;
                 json["no"]       = select_action.No;
                 json["function"] = select_action.function;
                 NetworkMain.SendMessage(json);
             }
         }
     }
 }
Ejemplo n.º 21
0
        public bool Initialize(Config birdieConfig)
        {
            // Don't allow re-use
            if (hasTerminated)
            {
                return(false);
            }

            // Set privileges
            Privileges.SetPrivileges();

            // Validate the config first
            bool isConfigValid = birdieConfig.Validate();

            if (!isConfigValid)
            {
                return(false);
            }

            Config = birdieConfig;

            // Create the network handler
            networkMain = new NetworkMain(this);

            // Register callbacks
            networkMain.OnClientConnect        = ClientConnect;
            networkMain.OnClientDisconnect     = ClientDisconnect;
            networkMain.OnCompleteDataReceived = DataReceived;

            bool isNetworkInitialized = networkMain.Start();

            if (!isNetworkInitialized)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 22
0
    void Start()
    {
        errorLog.AddLogLine("is server: " + isServer.ToString());
        gm = GameObject.Find("NetworkMain").GetComponent <NetworkMain>();

        if (isLocalPlayer)
        {
            if (isServer)
            {
                //gm = GameObject.Find("GM").GetComponent<NetworkMain>();
                //gm.Login(this);
                InitialServerPlayer();
            }
            else
            {
                InitialRemotePlayer();
            }
        }
        else
        {
            serverCtl = gm.serverCtl;
            remoteCtl = gm.remoteCtl;
        }
    }
Ejemplo n.º 23
0
    public void Save(string path = null, bool open = false)
    {
        if (path == null)
        {
            FileItem item = Preset.objects.InventoryWindow.Items[no];
            // 자동으로 파일 저장위치 고려
            string fname  = item.owner + "_" + item.UI_title.text;
            string name   = fname;
            string folder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Gachon-Files\\";
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            for (int i = 2; File.Exists(folder + name); i++)
            {
                //확장자 분리
                int temp = fname.LastIndexOf('.');
                if (temp == -1)
                {
                    name = fname + " (" + i + ")";
                }
                else
                {
                    name = fname.Substring(0, temp) + " (" + i + ")" + fname.Substring(temp);
                }
            }
            path = folder + name;
        }
        JObject json = new JObject();

        json["type"] = NetworkProtocol.File_Download;
        json["no"]   = no;
        json["path"] = path;
        json["open"] = open;
        NetworkMain.SendMessage(json);
    }
Ejemplo n.º 24
0
        private static void NetworkUpdate()
        {
            switch (SystemsContainer.Get <MainSystem>().NetworkState)
            {
            case ClientState.Disconnected:
            case ClientState.Connecting:
                //Kill all systems while disconnected/connecting
                SystemsHandler.KillAllSystems();
                return;

            case ClientState.Connected:
                SystemsContainer.Get <HandshakeSystem>().Enabled = true;
                break;

            case ClientState.Handshaking:
                SystemsContainer.Get <MainSystem>().Status = "Connection successful, handshaking";
                break;

            case ClientState.Authenticated:
                SystemsContainer.Get <PlayerConnectionSystem>().Enabled = true;
                SystemsContainer.Get <StatusSystem>().Enabled           = true;
                SystemsContainer.Get <StatusSystem>().MessageSender.SendPlayerStatus(SystemsContainer.Get <StatusSystem>().MyPlayerStatus);
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.TimeSyncing;
                break;

            case ClientState.TimeSyncing:
                SystemsContainer.Get <MainSystem>().Status        = "Handshaking successful, syncing server clock";
                SystemsContainer.Get <TimeSyncerSystem>().Enabled = true;
                if (SystemsContainer.Get <TimeSyncerSystem>().Synced)
                {
                    SystemsContainer.Get <MainSystem>().NetworkState = ClientState.TimeSynced;
                }
                else
                {
                    SystemsContainer.Get <TimeSyncerSystem>().MessageSender.SendTimeSyncRequest();
                }
                break;

            case ClientState.TimeSynced:
                LunaLog.Log("[LMP]: Time Synced!");
                SystemsContainer.Get <KerbalSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendKerbalsRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingKerbals;
                break;

            case ClientState.SyncingKerbals:
                SystemsContainer.Get <MainSystem>().Status = "Syncing kerbals";
                break;

            case ClientState.KerbalsSynced:
                SystemsContainer.Get <MainSystem>().Status      = "Kerbals synced";
                SystemsContainer.Get <SettingsSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendSettingsRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingSettings;
                break;

            case ClientState.SyncingSettings:
                SystemsContainer.Get <MainSystem>().Status = "Syncing settings";
                break;

            case ClientState.SettingsSynced:
                SystemsContainer.Get <MainSystem>().Status  = "Settings synced";
                SystemsContainer.Get <WarpSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendWarpSubspacesRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingWarpsubspaces;
                break;

            case ClientState.SyncingWarpsubspaces:
                SystemsContainer.Get <MainSystem>().Status = "Syncing warp subspaces";
                break;

            case ClientState.WarpsubspacesSynced:
                SystemsContainer.Get <MainSystem>().Status         = "Warp subspaces synced";
                SystemsContainer.Get <PlayerColorSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendColorsRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingColors;
                break;

            case ClientState.SyncingColors:
                SystemsContainer.Get <MainSystem>().Status = "Syncing player colors";
                break;

            case ClientState.ColorsSynced:
                SystemsContainer.Get <MainSystem>().Status = "Player colors synced";
                NetworkSimpleMessageSender.SendPlayersRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingPlayers;
                break;

            case ClientState.SyncingPlayers:
                SystemsContainer.Get <MainSystem>().Status = "Syncing players";
                break;

            case ClientState.PlayersSynced:
                SystemsContainer.Get <MainSystem>().Status      = "Players synced";
                SystemsContainer.Get <ScenarioSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendScenariosRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingScenarios;
                break;

            case ClientState.SyncingScenarios:
                SystemsContainer.Get <MainSystem>().Status = "Syncing scenarios";
                break;

            case ClientState.ScneariosSynced:
                SystemsContainer.Get <MainSystem>().Status          = "Scenarios synced";
                SystemsContainer.Get <CraftLibrarySystem>().Enabled = true;
                NetworkSimpleMessageSender.SendCraftLibraryRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingCraftlibrary;
                break;

            case ClientState.SyncingCraftlibrary:
                SystemsContainer.Get <MainSystem>().Status = "Syncing craft library";
                break;

            case ClientState.CraftlibrarySynced:
                SystemsContainer.Get <MainSystem>().Status  = "Craft library synced";
                SystemsContainer.Get <ChatSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendChatRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingChat;
                break;

            case ClientState.SyncingChat:
                SystemsContainer.Get <MainSystem>().Status = "Syncing chat";
                break;

            case ClientState.ChatSynced:
                SystemsContainer.Get <MainSystem>().Status  = "Chat synced";
                SystemsContainer.Get <LockSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendLocksRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingLocks;
                break;

            case ClientState.SyncingLocks:
                SystemsContainer.Get <MainSystem>().Status = "Syncing locks";
                break;

            case ClientState.LocksSynced:
                SystemsContainer.Get <MainSystem>().Status   = "Locks synced";
                SystemsContainer.Get <AdminSystem>().Enabled = true;
                NetworkSimpleMessageSender.SendAdminsRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingAdmins;
                break;

            case ClientState.SyncingAdmins:
                SystemsContainer.Get <MainSystem>().Status = "Syncing admins";
                break;

            case ClientState.AdminsSynced:
                SystemsContainer.Get <MainSystem>().Status               = "Admins synced";
                SystemsContainer.Get <VesselLockSystem>().Enabled        = true;
                SystemsContainer.Get <VesselPositionSystem>().Enabled    = true;
                SystemsContainer.Get <VesselPositionAltSystem>().Enabled = true;
                SystemsContainer.Get <VesselFlightStateSystem>().Enabled = true;
                SystemsContainer.Get <VesselUpdateSystem>().Enabled      = true;
                SystemsContainer.Get <VesselChangeSystem>().Enabled      = true;
                SystemsContainer.Get <VesselProtoSystem>().Enabled       = true;
                SystemsContainer.Get <VesselRemoveSystem>().Enabled      = true;
                SystemsContainer.Get <VesselImmortalSystem>().Enabled    = true;
                SystemsContainer.Get <VesselDockSystem>().Enabled        = true;
                SystemsContainer.Get <VesselRangeSystem>().Enabled       = true;
                NetworkSimpleMessageSender.SendVesselListRequest();
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.SyncingVessels;
                break;

            case ClientState.SyncingVessels:
                SystemsContainer.Get <MainSystem>().Status = "Syncing vessels";
                break;

            case ClientState.VesselsSynced:
                LunaLog.Log("[LMP]: Vessels Synced!");
                SystemsContainer.Get <MainSystem>().Status              = "Syncing universe time";
                SystemsContainer.Get <MainSystem>().NetworkState        = ClientState.TimeLocking;
                SystemsContainer.Get <FlagSystem>().Enabled             = true;
                SystemsContainer.Get <KerbalReassignerSystem>().Enabled = true;
                SystemsContainer.Get <FlagSystem>().SendFlagList();
                SystemsContainer.Get <PlayerColorSystem>().MessageSender.SendPlayerColorToServer();
                break;

            case ClientState.TimeLocking:
                if (SystemsContainer.Get <TimeSyncerSystem>().Synced)
                {
                    LunaLog.Log("[LMP]: Time Locked!");
                    SystemsContainer.Get <MainSystem>().Status       = "Starting game";
                    SystemsContainer.Get <MainSystem>().NetworkState = ClientState.TimeLocked;
                    SystemsContainer.Get <MainSystem>().StartGame    = true;
                }
                break;

            case ClientState.TimeLocked:
                SystemsContainer.Get <MainSystem>().NetworkState = ClientState.Starting;
                break;

            case ClientState.Starting:
                LunaLog.Log("[LMP]: All systems up and running! Poyekhali!!");
                if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
                {
                    SystemsContainer.Get <MainSystem>().Status = "Running";

                    SystemsContainer.Get <MotdSystem>().Enabled = true;

                    SystemsContainer.Get <MainSystem>().DisplayDisconnectMessage = false;
                    SystemsContainer.Get <MainSystem>().NetworkState             = ClientState.Running;

                    SystemsContainer.Get <AsteroidSystem>().Enabled = true;
                    SystemsContainer.Get <ToolbarSystem>().Enabled  = true;
                    NetworkSimpleMessageSender.SendMotdRequest();
                }
                break;

            case ClientState.Running:
                SystemsContainer.Get <MainSystem>().GameRunning = true;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            if (SystemsContainer.Get <MotdSystem>().DisplayMotd&& HighLogic.LoadedScene != GameScenes.LOADING)
            {
                SystemsContainer.Get <MotdSystem>().DisplayMotd = false;
                SystemsContainer.Get <ScenarioSystem>().UpgradeTheAstronautComplexSoTheGameDoesntBugOut();
                ScreenMessages.PostScreenMessage(SystemsContainer.Get <MotdSystem>().ServerMotd, 10f, ScreenMessageStyle.UPPER_CENTER);
                //Control locks will bug out the space centre sceen, so remove them before starting.
                NetworkMain.DeleteAllTheControlLocksSoTheSpaceCentreBugGoesAway();
            }
        }
Ejemplo n.º 25
0
        public override void Update()
        {
            switch (MainSystem.Singleton.NetworkState)
            {
            case ClientState.DISCONNECTED:
            case ClientState.CONNECTING:
                //Kill all systems while disconnected/connecting
                SystemsHandler.KillAllSystems();
                return;

            case ClientState.CONNECTED:
                HandshakeSystem.Singleton.Enabled = true;
                break;

            case ClientState.HANDSHAKING:
                MainSystem.Singleton.Status = "Connection successful, handshaking";
                break;

            case ClientState.AUTHENTICATED:
                PlayerConnectionSystem.Singleton.Enabled = true;
                StatusSystem.Singleton.Enabled           = true;
                StatusSystem.Singleton.MessageSender.SendPlayerStatus(StatusSystem.Singleton.MyPlayerStatus);
                MainSystem.Singleton.NetworkState = ClientState.TIME_SYNCING;
                break;

            case ClientState.TIME_SYNCING:
                MainSystem.Singleton.Status        = "Handshaking successful, syncing server clock";
                TimeSyncerSystem.Singleton.Enabled = true;
                if (TimeSyncerSystem.Singleton.Synced)
                {
                    MainSystem.Singleton.NetworkState = ClientState.TIME_SYNCED;
                }
                else
                {
                    TimeSyncerSystem.Singleton.MessageSender.SendTimeSyncRequest();
                }
                break;

            case ClientState.TIME_SYNCED:
                Debug.Log("[LMP]: Time Synced!");
                KerbalSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendKerbalsRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_KERBALS;
                break;

            case ClientState.SYNCING_KERBALS:
                MainSystem.Singleton.Status = "Syncing kerbals";
                break;

            case ClientState.KERBALS_SYNCED:
                MainSystem.Singleton.Status      = "Kerbals synced";
                SettingsSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendSettingsRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_SETTINGS;
                break;

            case ClientState.SYNCING_SETTINGS:
                MainSystem.Singleton.Status = "Syncing settings";
                break;

            case ClientState.SETTINGS_SYNCED:
                MainSystem.Singleton.Status  = "Settings synced";
                WarpSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendWarpSubspacesRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_WARPSUBSPACES;
                break;

            case ClientState.SYNCING_WARPSUBSPACES:
                MainSystem.Singleton.Status = "Syncing warp subspaces";
                break;

            case ClientState.WARPSUBSPACES_SYNCED:
                MainSystem.Singleton.Status         = "Warp subspaces synced";
                PlayerColorSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendColorsRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_COLORS;
                break;

            case ClientState.SYNCING_COLORS:
                MainSystem.Singleton.Status = "Syncing player colors";
                break;

            case ClientState.COLORS_SYNCED:
                MainSystem.Singleton.Status = "Player colors synced";
                NetworkSimpleMessageSender.SendPlayersRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_PLAYERS;
                break;

            case ClientState.SYNCING_PLAYERS:
                MainSystem.Singleton.Status = "Syncing players";
                break;

            case ClientState.PLAYERS_SYNCED:
                MainSystem.Singleton.Status      = "Players synced";
                ScenarioSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendScenariosRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_SCENARIOS;
                break;

            case ClientState.SYNCING_SCENARIOS:
                MainSystem.Singleton.Status = "Syncing scenarios";
                break;

            case ClientState.SCNEARIOS_SYNCED:
                MainSystem.Singleton.Status          = "Scenarios synced";
                CraftLibrarySystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendCraftLibraryRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_CRAFTLIBRARY;
                break;

            case ClientState.SYNCING_CRAFTLIBRARY:
                MainSystem.Singleton.Status = "Syncing craft library";
                break;

            case ClientState.CRAFTLIBRARY_SYNCED:
                MainSystem.Singleton.Status  = "Craft library synced";
                ChatSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendChatRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_CHAT;
                break;

            case ClientState.SYNCING_CHAT:
                MainSystem.Singleton.Status = "Syncing chat";
                break;

            case ClientState.CHAT_SYNCED:
                MainSystem.Singleton.Status  = "Chat synced";
                LockSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendLocksRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_LOCKS;
                break;

            case ClientState.SYNCING_LOCKS:
                MainSystem.Singleton.Status = "Syncing locks";
                break;

            case ClientState.LOCKS_SYNCED:
                MainSystem.Singleton.Status   = "Locks synced";
                AdminSystem.Singleton.Enabled = true;
                NetworkSimpleMessageSender.SendAdminsRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_ADMINS;
                break;

            case ClientState.SYNCING_ADMINS:
                MainSystem.Singleton.Status = "Syncing admins";
                break;

            case ClientState.ADMINS_SYNCED:
                MainSystem.Singleton.Status   = "Admins synced";
                VesselCommon.EnableAllSystems = true;
                NetworkSimpleMessageSender.SendVesselListRequest();
                MainSystem.Singleton.NetworkState = ClientState.SYNCING_VESSELS;
                break;

            case ClientState.SYNCING_VESSELS:
                MainSystem.Singleton.Status = "Syncing vessels";
                break;

            case ClientState.VESSELS_SYNCED:
                Debug.Log("[LMP]: Vessels Synced!");
                MainSystem.Singleton.Status              = "Syncing universe time";
                MainSystem.Singleton.NetworkState        = ClientState.TIME_LOCKING;
                FlagSystem.Singleton.Enabled             = true;
                KerbalReassignerSystem.Singleton.Enabled = true;
                FlagSystem.Singleton.SendFlagList();
                PlayerColorSystem.Singleton.MessageSender.SendPlayerColorToServer();
                break;

            case ClientState.TIME_LOCKING:
                if (TimeSyncerSystem.Singleton.Synced)
                {
                    Debug.Log("[LMP]: Time Locked!");
                    MainSystem.Singleton.Status       = "Starting game";
                    MainSystem.Singleton.NetworkState = ClientState.TIME_LOCKED;
                    MainSystem.Singleton.StartGame    = true;
                }
                break;

            case ClientState.TIME_LOCKED:
                MainSystem.Singleton.NetworkState = ClientState.STARTING;
                break;

            case ClientState.STARTING:
                Debug.Log("[LMP]: All systems up and running Poyekhali");
                if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
                {
                    MainSystem.Singleton.Status = "Running";

                    MotdSystem.Singleton.Enabled = true;

                    MainSystem.Singleton.DisplayDisconnectMessage = false;
                    MainSystem.Singleton.NetworkState             = ClientState.RUNNING;

                    AsteroidSystem.Singleton.Enabled = true;
                    ToolbarSystem.Singleton.Enabled  = true;
                    NetworkSimpleMessageSender.SendMotdRequest();
                }
                break;

            case ClientState.RUNNING:
                MainSystem.Singleton.GameRunning = true;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            if (MotdSystem.Singleton.DisplayMotd && (HighLogic.LoadedScene != GameScenes.LOADING))
            {
                MotdSystem.Singleton.DisplayMotd = false;
                ScenarioSystem.Singleton.UpgradeTheAstronautComplexSoTheGameDoesntBugOut();
                ScreenMessages.PostScreenMessage(MotdSystem.Singleton.ServerMotd, 10f, ScreenMessageStyle.UPPER_CENTER);
                //Control locks will bug out the space centre sceen, so remove them before starting.
                NetworkMain.DeleteAllTheControlLocksSoTheSpaceCentreBugGoesAway();
            }
        }
Ejemplo n.º 26
0
        private void DrawNetworkSettings()
        {
            _showAdvancedNetworkSettings = GUILayout.Toggle(_showAdvancedNetworkSettings, LocalizationContainer.OptionsWindowText.NetworkSettings, ButtonStyle);
            if (_showAdvancedNetworkSettings)
            {
                if (MainSystem.NetworkState > ClientState.Disconnected)
                {
                    GUILayout.Label(LocalizationContainer.OptionsWindowText.CannotChangeWhileConnected);
                }

                GUILayout.Label($"{LocalizationContainer.OptionsWindowText.Mtu} {NetworkMain.Config.MaximumTransmissionUnit}");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    if (NetworkMain.ClientConnection.Status != NetPeerStatus.NotRunning)
                    {
                        if (GUILayout.Button(LocalizationContainer.OptionsWindowText.ResetNetwork))
                        {
                            NetworkMain.ResetNetworkSystem();
                        }
                    }
                    else
                    {
                        var mtuValue = (int)Math.Round(GUILayout.HorizontalScrollbar(SettingsSystem.CurrentSettings.Mtu, 0, 1, NetworkMain.MaxMtuSize));
                        if (mtuValue != SettingsSystem.CurrentSettings.Mtu)
                        {
                            NetworkMain.Config.MaximumTransmissionUnit = SettingsSystem.CurrentSettings.Mtu = mtuValue;
                            SettingsSystem.SaveSettings();
                        }

                        var autoExpandValue = GUILayout.Toggle(SettingsSystem.CurrentSettings.AutoExpandMtu, LocalizationContainer.OptionsWindowText.AutoExpandMtu);
                        if (autoExpandValue != SettingsSystem.CurrentSettings.AutoExpandMtu)
                        {
                            NetworkMain.Config.AutoExpandMTU = SettingsSystem.CurrentSettings.AutoExpandMtu = autoExpandValue;
                            SettingsSystem.SaveSettings();
                        }
                    }
                }

                if (SettingsSystem.CurrentSettings.TimeoutSeconds == float.MaxValue)
                {
                    GUILayout.Label($"{LocalizationContainer.OptionsWindowText.ConnectionTimeout} ∞");
                }
                else
                {
                    GUILayout.Label($"{LocalizationContainer.OptionsWindowText.ConnectionTimeout} {NetworkMain.Config.ConnectionTimeout} sec");
                }
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    _infiniteTimeout = SettingsSystem.CurrentSettings.TimeoutSeconds == float.MaxValue;

                    GUI.enabled = !_infiniteTimeout;
                    var newTimeoutVal = (int)Math.Round(GUILayout.HorizontalScrollbar(SettingsSystem.CurrentSettings.TimeoutSeconds, 0, NetworkMain.Config.PingInterval, 120));
                    if (newTimeoutVal != SettingsSystem.CurrentSettings.TimeoutSeconds)
                    {
                        NetworkMain.Config.ConnectionTimeout = SettingsSystem.CurrentSettings.TimeoutSeconds = newTimeoutVal;
                        SettingsSystem.SaveSettings();
                    }
                    GUI.enabled = true;

                    _infiniteTimeout = GUILayout.Toggle(_infiniteTimeout, "∞", "toggle");
                    if (_infiniteTimeout)
                    {
                        NetworkMain.Config.ConnectionTimeout = SettingsSystem.CurrentSettings.TimeoutSeconds = float.MaxValue;
                        SettingsSystem.SaveSettings();
                    }
                }
            }
        }
Ejemplo n.º 27
0
        private void DrawAdvancedDebugOptions()
        {
            GUILayout.Label("Debug settings\n________________________________________");

            if (GUILayout.Button("Check Common.dll stock parts"))
            {
                ModSystem.Singleton.CheckCommonStockParts();
            }
            if (GUILayout.Button("Regenerate translation files"))
            {
                LocalizationContainer.RegenerateTranslations();
            }

            GUILayout.Space(10);

            _showBadNetworkSimulationSettings = GUILayout.Toggle(_showBadNetworkSimulationSettings, "Bad network simulation", ButtonStyle);
            if (_showBadNetworkSimulationSettings)
            {
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button("Random", ButtonStyle))
                    {
                        NetworkMain.RandomizeBadConnectionValues();
                    }
                    if (GUILayout.Button("Reset", ButtonStyle))
                    {
                        NetworkMain.ResetBadConnectionValues();
                    }
                    GUILayout.EndHorizontal();
                }

                if (MainSystem.NetworkState > ClientState.Disconnected)
                {
                    GUILayout.Label("Cannot change values while connected");
                }

                GUILayout.Label($"Packet loss: {NetworkMain.Config.SimulatedLoss * 100:F1}%");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedLoss = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedLoss, 0, 0, 1), 3);
                }
                GUILayout.Label($"Packet duplication: {NetworkMain.Config.SimulatedDuplicatesChance * 100:F1}%");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedDuplicatesChance = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedDuplicatesChance, 0, 0, 1), 3);
                }
                GUILayout.Label($"Max random latency: {NetworkMain.Config.SimulatedRandomLatency * 1000:F1} ms");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedRandomLatency = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedRandomLatency, 0, 0, 3), 4);
                }
                GUILayout.Label($"Min latency: {NetworkMain.Config.SimulatedMinimumLatency * 1000:F1} ms");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedMinimumLatency = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedMinimumLatency, 0, 0, 3), 4);
                }
            }

            _showClockOffsetSettings = GUILayout.Toggle(_showClockOffsetSettings, "Clock offset simulation", ButtonStyle);
            if (_showClockOffsetSettings)
            {
                GUILayout.Label($"Computer clock offset: {LunaComputerTime.SimulatedMinutesTimeOffset:F1} min");
                LunaComputerTime.SimulatedMinutesTimeOffset = (float)Math.Round(GUILayout.HorizontalScrollbar(LunaComputerTime.SimulatedMinutesTimeOffset, 0, -15, 15), 3);

                GUILayout.Label($"NTP server time offset: {LunaNetworkTime.SimulatedMsTimeOffset:F1} ms");
                LunaNetworkTime.SimulatedMsTimeOffset = (float)Math.Round(GUILayout.HorizontalScrollbar(LunaNetworkTime.SimulatedMsTimeOffset, 0, -2500, 2500), 3);
            }
        }
Ejemplo n.º 28
0
    void Run()
    {
        bool    JumpButton = false;
        Vector3 v          = new Vector3();

        if (UIInput.selection == null) // 다른 UIInput에 입력중이 아닌경우
        {
            if (Input.GetKey(KeyCode.A))
            {
                v += Vector3.left;
            }
            if (Input.GetKey(KeyCode.D))
            {
                v -= Vector3.left;
            }
            if (Input.GetKey(KeyCode.W))
            {
                v += Vector3.forward;
            }
            if (Input.GetKey(KeyCode.S))
            {
                v -= Vector3.forward;
            }
            if (Input.GetKey(KeyCode.Space))
            {
                JumpButton = true;
            }
        }
        if (cc.isGrounded)
        {
            if (JumpButton)
            {
                VSpeed = 14;
            }
            if (VSpeed < 0)
            {
                VSpeed = 0;
            }
        }
        if (Input.GetMouseButton(1))
        {
            transform.rotation = man.transform.rotation;
        }
        v       = v.normalized * Speed;
        VSpeed -= 40 * Time.deltaTime;
        v.y     = VSpeed;
        v       = transform.rotation * v;
        Vector3 vc = transform.position;

        cc.Move(v * Time.deltaTime);
        if (moveok)
        {
            if (movetime >= NetworkMain.MoveDeley)
            {
                moveok = false;
                JObject json = new JObject();
                json["type"] = NetworkProtocol.Move;
                json["x"]    = vc.x;
                json["y"]    = vc.y;
                json["z"]    = vc.z;
                json["q"]    = transform.rotation.eulerAngles.y;
                NetworkMain.SendMessage(json);
                movetime -= NetworkMain.MoveDeley;
            }
        }
        if (vc != transform.position || q != transform.rotation.eulerAngles.y)
        {
            q = transform.rotation.eulerAngles.y;
            if (movetime > NetworkMain.MoveDeley)
            {
                movetime = 0;
            }

            moveok = true;
        }
        movetime += Time.deltaTime;
    }
Ejemplo n.º 29
0
        private void NetworkUpdate()
        {
            switch (MainSystem.NetworkState)
            {
            case ClientState.DisconnectRequested:
            case ClientState.Disconnected:
                break;

            case ClientState.Connecting:
                ChangeRoutineExecutionInterval(RoutineExecution.Update, nameof(NetworkUpdate), 0);
                return;

            case ClientState.Connected:
                HandshakeSystem.Singleton.Enabled = true;
                MainSystem.Singleton.Status       = "Connected";
                MainSystem.NetworkState           = ClientState.Handshaking;
                HandshakeSystem.Singleton.MessageSender.SendHandshakeRequest();
                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.Handshaking:
                MainSystem.Singleton.Status = "Waiting for handshake response";
                if (ConnectionIsStuck(60000))
                {
                    LunaLog.Log("[LMP]: Failed to get a handshake response after 60 seconds. Sending the handshake again...");
                    MainSystem.NetworkState = ClientState.Connected;
                }
                break;

            case ClientState.Handshaked:
                MainSystem.Singleton.Status      = "Handshaking successful";
                SettingsSystem.Singleton.Enabled = true;
                MainSystem.NetworkState          = ClientState.SyncingSettings;
                SettingsSystem.Singleton.MessageSender.SendSettingsRequest();

                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.SyncingSettings:
                MainSystem.Singleton.Status = "Syncing settings";
                if (ConnectionIsStuck())
                {
                    MainSystem.NetworkState = ClientState.Handshaked;
                }
                break;

            case ClientState.SettingsSynced:
                MainSystem.Singleton.Status = "Settings synced";
                if (SettingsSystem.ValidateSettings())
                {
                    KerbalSystem.Singleton.Enabled      = true;
                    VesselProtoSystem.Singleton.Enabled = true;
                    VesselSyncSystem.Singleton.Enabled  = true;
                    VesselSyncSystem.Singleton.MessageSender.SendVesselsSyncMsg();
                    MainSystem.NetworkState = ClientState.SyncingKerbals;
                    KerbalSystem.Singleton.MessageSender.SendKerbalsRequest();
                    _lastStateTime = LunaComputerTime.UtcNow;
                }
                break;

            case ClientState.SyncingKerbals:
                MainSystem.Singleton.Status = "Syncing kerbals";
                if (ConnectionIsStuck(10000))
                {
                    MainSystem.NetworkState = ClientState.SettingsSynced;
                }
                break;

            case ClientState.KerbalsSynced:
                MainSystem.Singleton.Status  = "Kerbals synced";
                WarpSystem.Singleton.Enabled = true;
                MainSystem.NetworkState      = ClientState.SyncingWarpsubspaces;
                WarpSystem.Singleton.MessageSender.SendWarpSubspacesRequest();
                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.SyncingWarpsubspaces:
                MainSystem.Singleton.Status = "Syncing warp subspaces";
                if (ConnectionIsStuck())
                {
                    MainSystem.NetworkState = ClientState.KerbalsSynced;
                }
                break;

            case ClientState.WarpsubspacesSynced:
                MainSystem.Singleton.Status         = "Warp subspaces synced";
                PlayerColorSystem.Singleton.Enabled = true;
                MainSystem.NetworkState             = ClientState.SyncingColors;
                PlayerColorSystem.Singleton.MessageSender.SendColorsRequest();
                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.SyncingColors:
                MainSystem.Singleton.Status = "Syncing player colors";
                if (ConnectionIsStuck())
                {
                    MainSystem.NetworkState = ClientState.WarpsubspacesSynced;
                }
                break;

            case ClientState.ColorsSynced:
                MainSystem.Singleton.Status  = "Player colors synced";
                FlagSystem.Singleton.Enabled = true;
                MainSystem.NetworkState      = ClientState.SyncingFlags;
                FlagSystem.Singleton.MessageSender.SendFlagsRequest();
                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.SyncingFlags:
                MainSystem.Singleton.Status = "Syncing flags";
                if (ConnectionIsStuck(10000))
                {
                    MainSystem.NetworkState = ClientState.ColorsSynced;
                }
                break;

            case ClientState.FlagsSynced:
                MainSystem.Singleton.Status              = "Flags synced";
                StatusSystem.Singleton.Enabled           = true;
                PlayerConnectionSystem.Singleton.Enabled = true;
                MainSystem.NetworkState = ClientState.SyncingPlayers;
                StatusSystem.Singleton.MessageSender.SendPlayersRequest();
                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.SyncingPlayers:
                MainSystem.Singleton.Status = "Syncing players";
                if (ConnectionIsStuck())
                {
                    MainSystem.NetworkState = ClientState.FlagsSynced;
                }
                break;

            case ClientState.PlayersSynced:
                MainSystem.Singleton.Status      = "Players synced";
                ScenarioSystem.Singleton.Enabled = true;
                MainSystem.NetworkState          = ClientState.SyncingScenarios;
                ScenarioSystem.Singleton.MessageSender.SendScenariosRequest();
                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.SyncingScenarios:
                MainSystem.Singleton.Status = "Syncing scenarios";
                if (ConnectionIsStuck(10000))
                {
                    MainSystem.NetworkState = ClientState.PlayersSynced;
                }
                break;

            case ClientState.ScenariosSynced:
                MainSystem.Singleton.Status  = "Scenarios synced";
                MainSystem.NetworkState      = ClientState.SyncingLocks;
                LockSystem.Singleton.Enabled = true;
                LockSystem.Singleton.MessageSender.SendLocksRequest();
                _lastStateTime = LunaComputerTime.UtcNow;
                break;

            case ClientState.SyncingLocks:
                MainSystem.Singleton.Status = "Syncing locks";
                if (ConnectionIsStuck())
                {
                    MainSystem.NetworkState = ClientState.ScenariosSynced;
                }
                break;

            case ClientState.LocksSynced:
                MainSystem.Singleton.Status    = "Starting";
                MainSystem.Singleton.StartGame = true;
                MainSystem.NetworkState        = ClientState.Starting;
                break;

            case ClientState.Starting:
                //Once we start the game we don't need to run this routine on every frame
                ChangeRoutineExecutionInterval(RoutineExecution.Update, nameof(NetworkUpdate), 1500);
                MainSystem.Singleton.Status = "Running";
                CommonUtil.Reserve20Mb();
                LunaLog.Log("[LMP]: All systems up and running. Поехали!");
                if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
                {
                    MainSystem.NetworkState = ClientState.Running;
                    NetworkMain.DeleteAllTheControlLocksSoTheSpaceCentreBugGoesAway();
                }
                break;

            case ClientState.Running:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Ejemplo n.º 30
0
        private void DrawAdvancedDebugOptions()
        {
            var settingIntegrator = GUILayout.Toggle(SettingsSystem.CurrentSettings.OverrideIntegrator, "Override flight integrator", ButtonStyle);

            if (settingIntegrator != SettingsSystem.CurrentSettings.OverrideIntegrator)
            {
                SettingsSystem.CurrentSettings.OverrideIntegrator = settingIntegrator;
                SettingsSystem.SaveSettings();
            }
            if (GUILayout.Button("Check Common.dll stock parts"))
            {
                ModSystem.Singleton.CheckCommonStockParts();
            }
            GUILayout.Space(10);

            _showAdvancedNetworkFields = GUILayout.Toggle(_showAdvancedNetworkFields, "Advanced network fields", ButtonStyle);
            if (_showAdvancedNetworkFields)
            {
                if (MainSystem.NetworkState > ClientState.Disconnected)
                {
                    GUILayout.Label("Cannot change values while connected");
                }

                GUILayout.Label($"MTU: {NetworkMain.Config.MaximumTransmissionUnit}");
                GUILayout.Label(_infiniteTimeout
                    ? "Timeout: Infinite"
                    : $"Timeout: {NetworkMain.Config.ConnectionTimeout}s. Minimum: {NetworkMain.Config.PingInterval}s");

                GUILayout.BeginHorizontal();
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    _infiniteTimeout = GUILayout.Toggle(_infiniteTimeout, "Infinite", "toggle");
                    if (!_infiniteTimeout)
                    {
                        if (NetworkMain.Config.ConnectionTimeout >= float.MaxValue - 1)
                        {
                            NetworkMain.Config.ConnectionTimeout = 15;
                        }

                        var value = GUILayout.TextArea(NetworkMain.Config.ConnectionTimeout.ToString(CultureInfo.InvariantCulture), 32, TextAreaStyle);
                        if (float.TryParse(value, out var parsedResult))
                        {
                            if (parsedResult >= NetworkMain.Config.PingInterval)
                            {
                                NetworkMain.Config.ConnectionTimeout = parsedResult;
                            }
                        }
                    }
                    else
                    {
                        NetworkMain.Config.ConnectionTimeout = float.MaxValue;
                    }
                }
                GUILayout.EndHorizontal();
            }

            _showBadNetworkSimulationFields = GUILayout.Toggle(_showBadNetworkSimulationFields, "Bad network simulation", ButtonStyle);
            if (_showBadNetworkSimulationFields)
            {
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button("Random", ButtonStyle))
                    {
                        NetworkMain.RandomizeBadConnectionValues();
                    }
                    if (GUILayout.Button("Reset", ButtonStyle))
                    {
                        NetworkMain.ResetBadConnectionValues();
                    }
                    GUILayout.EndHorizontal();
                }

                GUILayout.Label($"NTP time offset: {LunaTime.SimulatedMsTimeOffset:F1}ms");
                LunaTime.SimulatedMsTimeOffset = (float)Math.Round(GUILayout.HorizontalScrollbar(LunaTime.SimulatedMsTimeOffset, 0, -2500, 2500), 3);
                if (MainSystem.NetworkState > ClientState.Disconnected)
                {
                    GUILayout.Label("Cannot change values while connected");
                }

                GUILayout.Label($"Packet loss: {NetworkMain.Config.SimulatedLoss * 100:F1}%");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedLoss = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedLoss, 0, 0, 1), 3);
                }
                GUILayout.Label($"Packet duplication: {NetworkMain.Config.SimulatedDuplicatesChance * 100:F1}%");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedDuplicatesChance = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedDuplicatesChance, 0, 0, 1), 3);
                }
                GUILayout.Label($"Max random latency: {NetworkMain.Config.SimulatedRandomLatency * 1000:F1} ms");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedRandomLatency = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedRandomLatency, 0, 0, 3), 4);
                }
                GUILayout.Label($"Min latency: {NetworkMain.Config.SimulatedMinimumLatency * 1000:F1} ms");
                if (MainSystem.NetworkState <= ClientState.Disconnected)
                {
                    NetworkMain.Config.SimulatedMinimumLatency = (float)Math.Round(GUILayout.HorizontalScrollbar(NetworkMain.Config.SimulatedMinimumLatency, 0, 0, 3), 4);
                }
            }
        }