Example #1
0
        private static void CreateBooleanControl(DisplayNameAttribute control, DescriptionAttribute descriptionAttr, PropertyInfo prop, Vector2 anchorPosition, RectTransform container)
        {
            RectTransform element = Object.Instantiate(checkboxTemplate, container, false);

            SetupUIElement(element, control, descriptionAttr, prop, anchorPosition);
            UIToggle toggle = element.GetComponentInChildren <UIToggle>();

            toggle.toggle.onValueChanged.RemoveAllListeners();
            toggle.toggle.onValueChanged.AddListener((value) => {
                // lock soil setting while in multiplayer game
                if (control.DisplayName == "Sync Soil" && Multiplayer.IsActive)
                {
                    // reset to saved value if needed
                    if (value != (bool)prop.GetValue(tempMultiplayerOptions, null))
                    {
                        toggle.isOn = !value;
                        InGamePopup.ShowInfo("Info", "This setting can only be changed while not in game", "Okay");
                    }
                    return;
                }
                prop.SetValue(tempMultiplayerOptions, value, null);
            });

            tempToUICallbacks[prop.Name] = () =>
            {
                toggle.isOn = (bool)prop.GetValue(tempMultiplayerOptions, null);
            };
        }
Example #2
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);
        }
Example #3
0
        private static void OnJoinGameButtonClick()
        {
            string[] parts = hostIPAdressInput.text.Split(':');
            string   ip    = parts[0].Trim();
            int      port;

            //remove copy and paste mistakes and update the textbox to prevent user confusion in case of invalid ip address
            hostIPAdressInput.text = parts.Length == 1 ? ip : ip + ":" + parts[1].Trim();

            if (parts.Length == 1)
            {
                port = Config.DefaultPort;
            }
            else if (!int.TryParse(parts[1], out port))
            {
                Log.Info($"Port must be a valid number above 1024");
                return;
            }

            // TODO: Should display a loader during the connection and only open the game once the player is connected to the server.
            multiplayerMenu.gameObject.SetActive(false);

            Log.Info($"Connecting to server... {ip}:{port}");
            if (!ConnectToServer(ip, port))
            {
                //re-enabling the menu again after failed connect attempt
                Log.Warn($"Was not able to connect to {hostIPAdressInput.text}");
                InGamePopup.ShowWarning("Connect failed", $"Was not able to connect to {hostIPAdressInput.text}", "OK");
                multiplayerMenu.gameObject.SetActive(true);
            }
        }
        private void ClientSocket_OnClose(object sender, CloseEventArgs e)
        {
            IsConnected      = false;
            serverConnection = null;

            UnityDispatchQueue.RunOnMainThread(() =>
            {
                // If the client is Quitting by himself, we don't have to inform him of his disconnection.
                if (e.Code == (ushort)DisconnectionReason.ClientRequestedDisconnect)
                {
                    return;
                }

                if (e.Code == (ushort)DisconnectionReason.ModVersionMismatch)
                {
                    string[] versions = e.Reason.Split(';');
                    InGamePopup.ShowWarning(
                        "Mod Version Mismatch",
                        $"Your Nebula Multiplayer Mod is not the same as the Host version.\nYou:{versions[0]} - Remote:{versions[1]}",
                        "OK",
                        OnDisconnectPopupCloseBeforeGameLoad);
                    return;
                }

                if (e.Code == (ushort)DisconnectionReason.GameVersionMismatch)
                {
                    string[] versions = e.Reason.Split(';');
                    InGamePopup.ShowWarning(
                        "Game Version Mismatch",
                        $"Your version of the game is not the same as the one used by the Host.\nYou:{versions[0]} - Remote:{versions[1]}",
                        "OK",
                        OnDisconnectPopupCloseBeforeGameLoad);
                    return;
                }

                if (SimulatedWorld.IsGameLoaded)
                {
                    InGamePopup.ShowWarning(
                        "Connection Lost",
                        $"You have been disconnected from the server.\n{e.Reason}",
                        "Quit",
                        () => LocalPlayer.LeaveGame());
                }
                else
                {
                    InGamePopup.ShowWarning(
                        "Server Unavailable",
                        $"Could not reach the server, please try again later.",
                        "OK",
                        () =>
                    {
                        LocalPlayer.IsMasterClient = false;
                        SimulatedWorld.Clear();
                        DestroySession();
                        OnDisconnectPopupCloseBeforeGameLoad();
                    });
                }
            });
        }
Example #5
0
 public static void FixedUpdate_Postfix(int ___frame)
 {
     InGamePopup.UpdateMessage("Loading", "Loading state from server, please wait\n" + Log.MessageInfo);
     if (Multiplayer.IsActive && ___frame >= 11)
     {
         Multiplayer.Session.OnGameLoadCompleted();
     }
 }
Example #6
0
 public static bool StarmapChangingToMilkyWay_Prefix(UIGame __instance)
 {
     if (Multiplayer.IsActive)
     {
         InGamePopup.ShowInfo("Access Denied", "Milky Way is disabled in multiplayer game.", "OK");
         return(false);
     }
     return(true);
 }
        public void ProcessPacket(HandshakeResponse packet, NebulaConnection conn)
        {
            GameDesc gameDesc = new GameDesc();

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

            LocalPlayer.IsMasterClient = false;
            LocalPlayer.SetPlayerData(packet.LocalPlayerData);

            InGamePopup.ShowInfo("Loading", "Loading state from server, please wait", null);
        }
        private void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
        {
            IsConnected      = false;
            serverConnection = null;

            InGamePopup.ShowWarning(
                "Connection Lost",
                $"You have been disconnect of the server.\nReason{disconnectInfo.Reason}",
                "Quit", "Reconnect",
                () => { LocalPlayer.LeaveGame(); },
                () => { Reconnect(); });
        }
Example #9
0
 public static bool SetViewStar_Prefix(DESelection __instance, ref StarData starData)
 {
     if (Multiplayer.IsActive && Multiplayer.Session.LocalPlayer.IsClient)
     {
         //UIDysonEditor._OnOpen()
         if (!UIRoot.instance.uiGame.dysonEditor.sceneGroup.activeSelf)
         {
             //Request the latest list of existing dyson spheres
             Multiplayer.Session.Network.SendPacket(new DysonSphereLoadRequest(0, DysonSphereRequestEvent.List));
             if (GameMain.localStar == null)
             {
                 //In outer space, set initial viewStar to the one that has dyson sphere
                 for (int i = 0; i < GameMain.data.dysonSpheres.Length; i++)
                 {
                     if (GameMain.data.dysonSpheres[i] != null)
                     {
                         starData = GameMain.data.dysonSpheres[i].starData;
                         return(true);
                     }
                 }
                 //No dyson sphere exist, close the UI
                 UIRoot.instance.uiGame.dysonEditor._Close();
                 return(false);
             }
             else if (GameMain.data.dysonSpheres[starData.index] == null)
             {
                 //Local dyson sphere hasn't loaded yet, close the UI
                 UIRoot.instance.uiGame.dysonEditor._Close();
                 return(false);
             }
         }
         if (starData != null && GameMain.data.dysonSpheres[starData.index] == null)
         {
             if (Multiplayer.Session.DysonSpheres.RequestingIndex == -1)
             {
                 Multiplayer.Session.DysonSpheres.RequestDysonSphere(starData.index);
             }
             else
             {
                 InGamePopup.ShowInfo("Loading", $"Loading Dyson sphere {starData.displayName}, please wait...", null);
             }
             // Restore comboBox back to original star
             UIComboBox dysonBox = UIRoot.instance.uiGame.dysonEditor.controlPanel.topFunction.dysonBox;
             int        index    = dysonBox.ItemsData.FindIndex(x => x == UIRoot.instance.uiGame.dysonEditor.selection.viewStar?.index);
             dysonBox.itemIndex = index >= 0 ? index : 0;
             return(false);
         }
     }
     return(true);
 }
Example #10
0
        public override void Start()
        {
            if (loadSaveFile)
            {
                SaveManager.LoadServerData();
            }

            foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies())
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
            }
            PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, true);

            foreach (Assembly assembly in NebulaModAPI.TargetAssemblies)
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
                PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, true);
            }
#if DEBUG
            PacketProcessor.SimulateLatency = true;
#endif

            socket = new WebSocketServer(System.Net.IPAddress.IPv6Any, port);
            DisableNagleAlgorithm(socket);
            WebSocketService.PacketProcessor = PacketProcessor;
            WebSocketService.PlayerManager   = PlayerManager;
            socket.AddWebSocketService <WebSocketService>("/socket", wse => new WebSocketService());
            try
            {
                socket.KeepClean = Config.Options.CleanupInactiveSessions;
                socket.Start();
            }catch (System.InvalidOperationException e)
            {
                InGamePopup.ShowError("Error", "An error occurred while hosting the game: " + e.Message, "Close");
                Stop();
                return;
            }

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = true;

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(new PlayerData(
                                                                             PlayerManager.GetNextAvailablePlayerId(),
                                                                             GameMain.localPlanet?.id ?? -1,
                                                                             Config.Options.GetMechaColors(),
                                                                             !string.IsNullOrWhiteSpace(Config.Options.Nickname) ? Config.Options.Nickname : GameMain.data.account.userName), loadSaveFile);

            NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
        }
Example #11
0
        private static IEnumerator TryConnectToServer(string ip, int port)
        {
            InGamePopup.ShowInfo("Connecting", $"Connecting to server {ip}:{port}...", null, null);
            multiplayerMenu.gameObject.SetActive(false);

            // We need to wait here to have time to display the Connecting popup since the game freezes during the connection.
            yield return(new WaitForSeconds(0.5f));

            if (!ConnectToServer(ip, port))
            {
                InGamePopup.FadeOut();
                //re-enabling the menu again after failed connect attempt
                InGamePopup.ShowWarning("Connect failed", $"Was not able to connect to {hostIPAdressInput.text}", "OK");
                multiplayerMenu.gameObject.SetActive(true);
            }
            else
            {
                InGamePopup.FadeOut();
            }
        }
        public void ProcessPacket(HandshakeRequest packet, NebulaConnection conn)
        {
            Player player;

            if (!playerManager.PendingPlayers.TryGetValue(conn, out player))
            {
                conn.Disconnect();
                Log.Warn("WARNING: Player tried to handshake without being in the pending list");
                return;
            }

            playerManager.PendingPlayers.Remove(conn);

            if (packet.ProtocolVersion != 0) //TODO: Maybe have a shared constants file somewhere for this
            {
                conn.Disconnect();
            }

            //
            GameMain.Pause();
            InGamePopup.ShowInfo("Loading", "Player joining the game, please wait", null);

            // Make sure that each player that is currently in the game receives that a new player as join so they can create its RemotePlayerCharacter
            foreach (Player activePlayer in playerManager.GetConnectedPlayers())
            {
                activePlayer.SendPacket(new PlayerJoining(player.Data));
            }

            // Add the new player to the list
            playerManager.SyncingPlayers.Add(conn, player);

            // TODO: This should be our actual GameDesc and not an hardcoded value.
            var inGamePlayersIds = playerManager.GetAllPlayerIdsIncludingHost();

            var gameDesc = GameMain.data.gameDesc;

            player.SendPacket(new HandshakeResponse(gameDesc.galaxyAlgo, gameDesc.galaxySeed, gameDesc.starCount, gameDesc.resourceMultiplier, player.Data, inGamePlayersIds.ToArray()));

            SimulatedWorld.SpawnRemotePlayerModel(player.Data);
        }
Example #13
0
        public static void _OnOpen_Postfix(UIGalaxySelect __instance)
        {
            if (Multiplayer.IsActive && Multiplayer.Session.LocalPlayer.IsClient)
            {
                RectTransform galaxySelectRect = __instance.gameObject.GetComponent <RectTransform>();

                galaxySelectRect.Find("star-count").gameObject.SetActive(false);
                galaxySelectRect.Find("resource-multiplier").gameObject.SetActive(false);
                galaxySelectRect.Find("galaxy-seed").GetComponentInChildren <InputField>().enabled = false;
                galaxySelectRect.Find("random-button").gameObject.SetActive(false);
                galaxySelectRect.Find("property-multiplier").gameObject.SetActive(false);
                galaxySelectRect.Find("seed-key").gameObject.SetActive(false);
            }
            if (Multiplayer.IsActive)
            {
                // show lobby hints if needed
                if (Config.Options.ShowLobbyHints)
                {
                    InGamePopup.ShowInfo("The Lobby",
                                         "We changed the start of a new multiplayer game a bit and want to give you a quick overview of the new feature.\n\n" +
                                         "Clients can now join while the host is in the galaxy selection screen, and they will also land there if it is their first time connecting to the currently hosted save.\n\n" +
                                         "You can now click on any star to bring up the solar system preview. From there you can click on any planet to bring up its details.\n" +
                                         "Note that when using GalacticScale 2 this process can take a bit longer.\n\n" +
                                         "By clicking a planet while having its detail panel open you will set it as your birth planet.\n\n" +
                                         "By clicking into outer space you will go one detail level up.\n\n" +
                                         "We hope you enjoy this new feature!",
                                         "Okay, cool :)",
                                         CloseLobbyInfo);
                }
                // prepare PlanetModelingManager for the use of its compute thread as we need that for the planet details view in the lobby
                PlanetModelingManager.PrepareWorks();
                // store current star id because entering the solar system details view messes up the main menu background system.
                if (MainMenuStarID == -1)
                {
                    MainMenuStarID = GameMain.localStar.id;
                }
                Button button = GameObject.Find("UI Root/Overlay Canvas/Galaxy Select/start-button").GetComponent <Button>();
                button.interactable = true;
            }
        }
Example #14
0
        private void ClientSocket_OnClose(object sender, CloseEventArgs e)
        {
            IsConnected      = false;
            serverConnection = null;

            // If the client is Quitting by himself, we don't have to inform him of his disconnection.
            if (e.Code == (ushort)NebulaStatusCode.ClientRequestedDisconnect)
            {
                return;
            }

            if (SimulatedWorld.IsGameLoaded)
            {
                UnityDispatchQueue.RunOnMainThread(() =>
                {
                    InGamePopup.ShowWarning(
                        "Connection Lost",
                        $"You have been disconnect of the server.\n{e.Reason}",
                        "Quit", "Reconnect",
                        () => { LocalPlayer.LeaveGame(); },
                        () => { Reconnect(); });
                });
            }
            else
            {
                UnityDispatchQueue.RunOnMainThread(() =>
                {
                    InGamePopup.ShowWarning(
                        "Server Unavailable",
                        $"Could not reach the server, please try again later.",
                        "OK",
                        () =>
                    {
                        GameObject overlayCanvasGo = GameObject.Find("Overlay Canvas");
                        Transform multiplayerMenu  = overlayCanvasGo?.transform?.Find("Nebula - Multiplayer Menu");
                        multiplayerMenu?.gameObject?.SetActive(true);
                    });
                });
            }
        }
Example #15
0
        public void ProcessPacket(HandshakeResponse packet, NebulaConnection conn)
        {
            if (LocalPlayer.GS2_GSSettings != null && packet.CompressedGS2Settings.Length > 1) // if host does not use GS2 we send a null byte
            {
                LocalPlayer.GS2ApplySettings(packet.CompressedGS2Settings);
            }
            else if (LocalPlayer.GS2_GSSettings != null && packet.CompressedGS2Settings.Length == 1)
            {
                InGamePopup.ShowWarning("Galactic Scale - Server not supported", "The server does not seem to use Galactic Scale. Make sure that your mod configuration matches.", "Close");
                return;
            }

            GameDesc gameDesc = new GameDesc();

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

            LocalPlayer.IsMasterClient = false;
            LocalPlayer.SetPlayerData(packet.LocalPlayerData);

            InGamePopup.ShowInfo("Loading", "Loading state from server, please wait", null);
        }
Example #16
0
        public void ProcessPacket(SyncComplete packet, NebulaConnection conn)
        {
            Player player = playerManager.GetSyncingPlayer(conn);

            if (player == null)
            {
                Log.Warn("Received a SyncComplete packet, but no player is joining.");
                return;
            }

            playerManager.SyncingPlayers.Remove(player.Connection);
            playerManager.ConnectedPlayers.Add(player.Connection, player);

            if (playerManager.SyncingPlayers.Count == 0)
            {
                playerManager.SendPacketToOtherPlayers(new SyncComplete(), player);
            }

            // Unpause the game
            InGamePopup.FadeOut();
            GameMain.Resume();
        }
Example #17
0
    void Start()
    {
        SettingsManager.CheckAPIKey();

        resourceTypePopup = new InGamePopup(new Rect(120, 270, 250, 30), 30f, resourceTypes);
    }
        public override void ProcessPacket(StartGameMessage packet, NebulaConnection conn)
        {
            if (IsHost)
            {
                if (Multiplayer.Session.IsGameLoaded && !GameMain.isFullscreenPaused)
                {
                    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 the game without being in the pending list");
                            return;
                        }

                        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);

                    conn.SendPacket(new StartGameMessage(true, (PlayerData)player.Data, Config.Options.SyncSoil));
                }
                else
                {
                    conn.SendPacket(new StartGameMessage(false, null, false));
                }
            }
            else if (packet.IsAllowedToStart)
            {
                // 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, true);

                UIRoot.instance.uiGame.planetDetail.gameObject.SetActive(false);
                Multiplayer.Session.IsInLobby      = false;
                Multiplayer.ShouldReturnToJoinMenu = false;

                DSPGame.StartGameSkipPrologue(UIRoot.instance.galaxySelect.gameDesc);

                InGamePopup.ShowInfo("Loading", "Loading state from server, please wait", null);
            }
            else
            {
                InGamePopup.ShowInfo("Please Wait", "The host is not ready to let you in, please wait!", "Okay");
            }
        }
Example #19
0
 public void ProcessPacket(PlayerJoining packet, NebulaConnection conn)
 {
     SimulatedWorld.SpawnRemotePlayerModel(packet.PlayerData);
     GameMain.Pause();
     InGamePopup.ShowInfo("Loading", "Player joining the game, please wait", null);
 }
Example #20
0
        public override void Start()
        {
            if (loadSaveFile)
            {
                SaveManager.LoadServerData();
            }

            foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies())
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
            }
            PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, true);

            foreach (Assembly assembly in NebulaModAPI.TargetAssemblies)
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
                PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, true);
            }
#if DEBUG
            PacketProcessor.SimulateLatency = true;
#endif

            if (Config.Options.EnableUPnpOrPmpSupport)
            {
                Task.Run(async() => {
                    var discoverer = new NatDiscoverer();
                    try
                    {
                        var device = await discoverer.DiscoverDeviceAsync();
                        await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, "DSP nebula"));
                        NebulaModel.Logger.Log.Info($"Successfully created UPnp or Pmp port mapping for {port}");
                    }
                    catch (NatDeviceNotFoundException)
                    {
                        NebulaModel.Logger.Log.WarnInform("No UPnp or Pmp compatible/enabled NAT device found");
                    }
                    catch (MappingException)
                    {
                        NebulaModel.Logger.Log.WarnInform("Could not create UPnp or Pmp port mapping");
                    }
                });
            }

            ngrokManager = new Ngrok.NgrokManager(port);

            socket                       = new WebSocketServer(System.Net.IPAddress.IPv6Any, port);
            socket.Log.Level             = LogLevel.Debug;
            socket.AllowForwardedRequest = true; // This is required to make the websocket play nice with tunneling services like ngrok

            if (!string.IsNullOrWhiteSpace(Config.Options.ServerPassword))
            {
                socket.AuthenticationSchemes = AuthenticationSchemes.Basic;
                socket.UserCredentialsFinder = id => {
                    var name = id.Name;

                    // Return user name, password, and roles.
                    return(name == "nebula-player"
                           ? new NetworkCredential(name, Config.Options.ServerPassword)
                           : null); // If the user credentials are not found.
                };
            }

            DisableNagleAlgorithm(socket);
            WebSocketService.PacketProcessor = PacketProcessor;
            WebSocketService.PlayerManager   = PlayerManager;
            socket.AddWebSocketService <WebSocketService>("/socket", wse => new WebSocketService());
            try
            {
                socket.KeepClean = Config.Options.CleanupInactiveSessions;
                socket.Start();
            }catch (System.InvalidOperationException e)
            {
                InGamePopup.ShowError("Error", "An error occurred while hosting the game: " + e.Message, "Close");
                Stop();
                return;
            }

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = true;

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(new PlayerData(
                                                                             PlayerManager.GetNextAvailablePlayerId(),
                                                                             GameMain.localPlanet?.id ?? -1,
                                                                             Config.Options.GetMechaColors(),
                                                                             !string.IsNullOrWhiteSpace(Config.Options.Nickname) ? Config.Options.Nickname : GameMain.data.account.userName), loadSaveFile);

            Task.Run(async() =>
            {
                if (ngrokManager.IsNgrokActive())
                {
                    DiscordManager.UpdateRichPresence(ip: await ngrokManager.GetNgrokAddressAsync(), updateTimestamp: true);
                }
                else
                {
                    DiscordManager.UpdateRichPresence(ip: $"{(Config.Options.IPConfiguration != IPUtils.IPConfiguration.IPv6 ? await IPUtils.GetWANv4Address() : string.Empty)};" +
                                                      $"{(Config.Options.IPConfiguration != IPUtils.IPConfiguration.IPv4 ? await IPUtils.GetWANv6Address() : string.Empty)};" +
                                                      $"{port}",
                                                      updateTimestamp: true);
                }
            });

            NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
        }
Example #21
0
 private static void CloseLobbyInfo()
 {
     InGamePopup.FadeOut();
     Config.Options.ShowLobbyHints = false;
     Config.SaveOptions();
 }
Example #22
0
        public static IEnumerable <CodeInstruction> Import_Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator il)
        {
            CodeMatcher matcher = new CodeMatcher(instructions, il)
                                  .MatchForward(false,
                                                new CodeMatch(OpCodes.Ldloc_S),
                                                new CodeMatch(OpCodes.Ldc_I4_1),
                                                new CodeMatch(OpCodes.Add),
                                                new CodeMatch(OpCodes.Stloc_S),
                                                new CodeMatch(OpCodes.Ldloc_S),
                                                new CodeMatch(OpCodes.Ldarg_0),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetFactory), "veinCursor")),
                                                new CodeMatch(OpCodes.Blt))
                                  .CreateLabel(out Label jmpForLoopIncrement)
                                  .Start()
                                  .MatchForward(false,
                                                new CodeMatch(OpCodes.Ldarg_0),
                                                new CodeMatch(i => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "get_planet"),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetData), "veinGroups")),
                                                new CodeMatch(OpCodes.Ldarg_0),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetFactory), "veinPool")),
                                                new CodeMatch(OpCodes.Ldloc_S),
                                                new CodeMatch(OpCodes.Ldelema),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(VeinData), "groupIndex")),
                                                new CodeMatch(OpCodes.Ldelema),
                                                new CodeMatch(OpCodes.Ldflda),
                                                new CodeMatch(OpCodes.Dup))
                                  .InsertAndAdvance(
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldloc_S, 29))
                                  .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate <BoundsChecker>((PlanetFactory factory, int index) =>
            {
                if (factory.veinPool[index].groupIndex >= factory.planet.veinGroups.Length && Multiplayer.IsActive)
                {
                    if (Multiplayer.Session.LocalPlayer.IsHost)
                    {
                        if (FaultyVeins.ContainsKey(factory.planetId))
                        {
                            FaultyVeins[factory.planetId].Add(index);
                        }
                        else
                        {
                            List <int> veins = new List <int>();
                            veins.Add(index);
                            FaultyVeins.Add(factory.planetId, veins);
                        }
                    }
                    if (index == factory.veinCursor - 1)
                    {
                        if (Multiplayer.Session.LocalPlayer.IsClient && !CheckPopupPresent.Contains(factory.planetId))
                        {
                            WarningManager.DisplayTemporaryWarning("IndexOutOfBounds while importing factory data. Host should fix his savefile.", 15000);
                            CheckPopupPresent.Add(factory.planetId);
                        }
                        else if (Multiplayer.Session.LocalPlayer.IsHost && !CheckPopupPresent.Contains(factory.planetId))
                        {
                            InGamePopup.ShowError("IndexOutOfBounds", $"Nebula detected an IndexOutOfBounds error while importing PlanetFactory data. This is very weird and rare, but we can try to fix it. Keep in mind this will possibly end in weird results but may makes this save usable again. We would need to remove {FaultyVeins[factory.planetId].Count} veins from {factory.planet.displayName}. Make a backup before trying the fix!", "Ignore", "Try to fix it", new Action(delegate() { }), new Action(delegate()
                            {
                                for (int i = 0; i < FaultyVeins[factory.planetId].Count; i++)
                                {
                                    factory.RemoveVeinWithComponents(FaultyVeins[factory.planetId][i]);
                                }
                                WarningManager.DisplayTemporaryWarning("Done performing the fix, hopefully you dont see me again.", 15000);
                                FaultyVeins[factory.planetId].Clear();
                            }));
                            CheckPopupPresent.Add(factory.planetId);
                        }
                    }
                    return(false);
                }
                return(true);
            }))
                                  .Insert(new CodeInstruction(OpCodes.Brfalse, jmpForLoopIncrement));

            return(matcher.InstructionEnumeration());
        }
Example #23
0
        private void ClientSocket_OnClose(object sender, CloseEventArgs e)
        {
            serverConnection = null;

            UnityDispatchQueue.RunOnMainThread(() =>
            {
                // If the client is Quitting by himself, we don't have to inform him of his disconnection.
                if (e.Code == (ushort)DisconnectionReason.ClientRequestedDisconnect)
                {
                    return;
                }

                // Opens the pause menu on disconnection to prevent NRE when leaving the game
                if (Multiplayer.Session?.IsGameLoaded ?? false)
                {
                    GameMain.instance._paused = true;
                }

                if (e.Code == (ushort)DisconnectionReason.ModIsMissing)
                {
                    InGamePopup.ShowWarning(
                        "Mod Mismatch",
                        $"You are missing mod {e.Reason}",
                        "OK".Translate(),
                        Multiplayer.LeaveGame);
                    return;
                }

                if (e.Code == (ushort)DisconnectionReason.ModIsMissingOnServer)
                {
                    InGamePopup.ShowWarning(
                        "Mod Mismatch",
                        $"Server is missing mod {e.Reason}",
                        "OK".Translate(),
                        Multiplayer.LeaveGame);
                    return;
                }

                if (e.Code == (ushort)DisconnectionReason.ModVersionMismatch)
                {
                    string[] versions = e.Reason.Split(';');
                    InGamePopup.ShowWarning(
                        "Mod Version Mismatch",
                        $"Your mod {versions[0]} version is not the same as the Host version.\nYou:{versions[1]} - Remote:{versions[2]}",
                        "OK".Translate(),
                        Multiplayer.LeaveGame);
                    return;
                }

                if (e.Code == (ushort)DisconnectionReason.GameVersionMismatch)
                {
                    string[] versions = e.Reason.Split(';');
                    InGamePopup.ShowWarning(
                        "Game Version Mismatch",
                        $"Your version of the game is not the same as the one used by the Host.\nYou:{versions[0]} - Remote:{versions[1]}",
                        "OK".Translate(),
                        Multiplayer.LeaveGame);
                    return;
                }

                if (e.Code == (ushort)DisconnectionReason.ProtocolError && websocketAuthenticationFailure)
                {
                    InGamePopup.AskInput(
                        "Server Requires Password",
                        "Server is protected. Please enter the correct password:"******"Connection Lost",
                        $"You have been disconnected from the server.\n{e.Reason}",
                        "Quit",
                        Multiplayer.LeaveGame);
                    if (Multiplayer.Session.IsInLobby)
                    {
                        Multiplayer.ShouldReturnToJoinMenu = false;
                        Multiplayer.Session.IsInLobby      = false;
                        UIRoot.instance.galaxySelect.CancelSelect();
                    }
                }
                else
                {
                    InGamePopup.ShowWarning(
                        "Server Unavailable",
                        $"Could not reach the server, please try again later.",
                        "OK".Translate(),
                        Multiplayer.LeaveGame);
                }
            });
        }
Example #24
0
 public void ProcessPacket(SyncComplete packet, NebulaConnection conn)
 {
     InGamePopup.FadeOut();
     GameMain.Resume();
 }
Example #25
0
    void Start()
    {
        SettingsManager.CheckAPIKey();

        resourceTypePopup = new InGamePopup(new Rect(120, 270, 250, 30), 30f, resourceTypes);
    }
Example #26
0
        public NgrokManager(int port, string authtoken = null, string region = null)
        {
            _ngrokConfigPath = Path.Combine(Path.GetDirectoryName(_ngrokPath), "ngrok.yml");
            _port            = port;
            _authtoken       = authtoken ?? Config.Options.NgrokAuthtoken;
            _region          = region ?? Config.Options.NgrokRegion;

            if (!NgrokEnabled)
            {
                return;
            }

            if (string.IsNullOrEmpty(_authtoken))
            {
                NebulaModel.Logger.Log.WarnInform("Ngrok support was enabled, however no Authtoken was provided");
                return;
            }

            // Validate the Ngrok region
            string[] availableRegions = { "us", "eu", "au", "ap", "sa", "jp", "in" };
            if (!string.IsNullOrEmpty(_region) && !availableRegions.Any(_region.Contains))
            {
                NebulaModel.Logger.Log.WarnInform("Unsupported Ngrok region was provided, defaulting to autodetection");
                _region = null;
            }

            // Start this stuff in it's own thread, as we require async and we dont want to freeze up the GUI when freeze up when Downloading and installing ngrok
            Task.Run(async() =>
            {
                if (!IsNgrokInstalled())
                {
                    var downloadAndInstallConfirmationSource = new TaskCompletionSource <bool>();

                    UnityDispatchQueue.RunOnMainThread(() =>
                    {
                        InGamePopup.ShowWarning(
                            "Ngrok download and installation confirmation",
                            "Ngrok support is enabled, however it has not been downloaded and installed yet, do you want to automatically download and install Ngrok?",
                            "Accept",
                            "Reject",
                            () => downloadAndInstallConfirmationSource.TrySetResult(true),
                            () => downloadAndInstallConfirmationSource.TrySetResult(false)
                            );
                    });

                    var hasDownloadAndInstallBeenConfirmed = await downloadAndInstallConfirmationSource.Task;
                    if (!hasDownloadAndInstallBeenConfirmed)
                    {
                        NebulaModel.Logger.Log.Warn("Failed to download or install Ngrok, because user rejected Ngrok download and install confirmation!");
                        return;
                    }

                    try
                    {
                        await DownloadAndInstallNgrok();
                    }
                    catch
                    {
                        NebulaModel.Logger.Log.WarnInform("Failed to download or install Ngrok!");
                        throw;
                    }
                }

                if (!StartNgrok())
                {
                    NebulaModel.Logger.Log.WarnInform($"Failed to start Ngrok tunnel! LastErrorCode: {NgrokLastErrorCode}");
                    return;
                }

                if (!IsNgrokActive())
                {
                    NebulaModel.Logger.Log.WarnInform($"Ngrok tunnel has exited prematurely! LastErrorCode: {NgrokLastErrorCode}");
                    return;
                }
            });
        }
Example #27
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;
            }
        }