public void Connect(string ip, int port) { serverIp = ip; serverPort = port; EventBasedNetListener listener = new EventBasedNetListener(); listener.PeerConnectedEvent += OnPeerConnected; listener.PeerDisconnectedEvent += OnPeerDisconnected; listener.NetworkReceiveEvent += OnNetworkReceive; client = new NetManager(listener) { AutoRecycle = true, }; PacketProcessor = new NetPacketProcessor(); LiteNetLibUtils.RegisterAllPacketNestedTypes(PacketProcessor); LiteNetLibUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor); client.Start(); client.Connect(ip, port, "nebula"); SimulatedWorld.Initialize(); LocalPlayer.IsMasterClient = false; LocalPlayer.SetNetworkProvider(this); }
public void Connect(string ip, int port) { serverIp = ip; serverPort = port; clientSocket = new WebSocket($"ws://{ip}:{port}/socket"); clientSocket.OnOpen += ClientSocket_OnOpen; clientSocket.OnClose += ClientSocket_OnClose; clientSocket.OnMessage += ClientSocket_OnMessage; PacketProcessor = new NetPacketProcessor(); #if DEBUG PacketProcessor.SimulateLatency = true; #endif PacketUtils.RegisterAllPacketNestedTypes(PacketProcessor); PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor); clientSocket.Connect(); SimulatedWorld.Initialize(); LocalPlayer.IsMasterClient = false; LocalPlayer.SetNetworkProvider(this); }
public static void OnPlanetDataSet_Postfix() { if (Multiplayer.IsActive && Multiplayer.Session.IsInLobby) { GameMain.history.universeObserveLevel = SimulatedWorld.GetUniverseObserveLevel(); } }
public override void ProcessPacket(NewDroneOrderPacket packet, NebulaConnection conn) { // Host does not need to know about flying drones of other players if he is not on the same planet if (IsHost) { if (GameMain.mainPlayer.planetId != packet.PlanetId) { return; } Player player = playerManager.GetPlayer(conn); if (player != null) { if (packet.Stage == 1 || packet.Stage == 2) { DroneManager.AddPlayerDronePlan(player.Id, packet.EntityId); } else if (packet.Stage == 3) { DroneManager.RemovePlayerDronePlan(player.Id, packet.EntityId); } } } SimulatedWorld.UpdateRemotePlayerDrone(packet); }
public static void FixedUpdate_Postfix(int ___frame) { if (___frame >= 11 && SimulatedWorld.Initialized) { SimulatedWorld.OnGameLoadCompleted(); } }
public void ProcessPacket(StationUI packet, NebulaConnection conn) { Player player = playerManager.GetPlayer(conn); // if a user adds/removes a ship, drone or warper or changes max power input broadcast to everyone. if ((packet.settingIndex == StationUI.UIsettings.MaxChargePower || packet.settingIndex == StationUI.UIsettings.setDroneCount || packet.settingIndex == StationUI.UIsettings.setShipCount || packet.settingIndex == StationUI.UIsettings.setWarperCount) && player != null && StationUIManager.UpdateCooldown == 0) { playerManager.SendPacketToAllPlayers(packet); } else if (StationUIManager.UpdateCooldown == 0 || !packet.isStorageUI) { List <NebulaConnection> subscribers = StationUIManager.GetSubscribers(packet.stationGId); for (int i = 0; i < subscribers.Count; i++) { if (subscribers[i] != null) { if (subscribers[i] == conn) { /* * as we block the normal method for the client he must run it once he receives this packet. * but only the one issued the request should do it, we indicate this here */ packet.shouldMimick = true; } subscribers[i].SendPacket(packet); } } } // always update values for host SimulatedWorld.OnStationUIChange(packet); }
public static void OnClose_Postfix(UIStarmap __instance) { if (SimulatedWorld.Initialized) { SimulatedWorld.ClearPlayerNameTagsOnStarmap(); } }
public void StartServer(int port, bool loadSaveFile = false) { PlayerManager = new PlayerManager(); if (loadSaveFile) { SaveManager.LoadServerData(); } SaveManager.SaveOnExit = true; PacketProcessor = new NetPacketProcessor(); StatisticsManager = new StatisticsManager(); #if DEBUG PacketProcessor.SimulateLatency = true; #endif PacketUtils.RegisterAllPacketNestedTypes(PacketProcessor); PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor); socketServer = new WebSocketServer(port); socketServer.AddWebSocketService("/socket", () => new WebSocketService(PlayerManager, PacketProcessor)); socketServer.Start(); SimulatedWorld.Initialize(); LocalPlayer.SetNetworkProvider(this); LocalPlayer.IsMasterClient = true; // TODO: Load saved player info here LocalPlayer.SetPlayerData(new PlayerData(PlayerManager.GetNextAvailablePlayerId(), GameMain.localPlanet?.id ?? -1, new Float3(1.0f, 0.6846404f, 0.243137181f))); }
public static void OnDraw_Postfix() { if (SimulatedWorld.Initialized) { SimulatedWorld.OnDronesDraw(); } }
public void ProcessPacket(StationUI packet, NebulaConnection conn) { Player player = playerManager.GetPlayer(conn); // if a user adds/removes a ship, drone or warper broadcast to everyone. if ((packet.settingIndex == 0 || packet.settingIndex == 8 || packet.settingIndex == 9 || packet.settingIndex == 10) && player != null && StationUIManager.UpdateCooldown == 0) { playerManager.SendPacketToAllPlayers(packet); } else if (StationUIManager.UpdateCooldown == 0 || !packet.isStorageUI) { List <NebulaConnection> subscribers = StationUIManager.GetSubscribers(packet.stationGId); for (int i = 0; i < subscribers.Count; i++) { if (subscribers[i] != null) { if (subscribers[i] == conn) { packet.shouldMimick = true; } Debug.Log("sending packet to subscriber"); subscribers[i].SendPacket(packet); } } } SimulatedWorld.OnStationUIChange(packet); }
public override void ProcessPacket(PlayerMovement packet, NebulaConnection conn) { bool valid = true; if (IsHost) { Player player = playerManager.GetPlayer(conn); if (player != null) { player.Data.LocalPlanetId = packet.LocalPlanetId; player.Data.UPosition = packet.UPosition; player.Data.Rotation = packet.Rotation; player.Data.BodyRotation = packet.BodyRotation; player.Data.LocalPlanetPosition = packet.LocalPlanetPosition; playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { SimulatedWorld.UpdateRemotePlayerPosition(packet); } }
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; } // Should these be locked together? int syncingCount; using (playerManager.GetSyncingPlayers(out var syncingPlayers)) { bool removed = syncingPlayers.Remove(player.Connection); syncingCount = syncingPlayers.Count; } using (playerManager.GetConnectedPlayers(out var connectedPlayers)) { connectedPlayers.Add(player.Connection, player); } // Since the player is now connected, we can safely spawn his player model SimulatedWorld.SpawnRemotePlayerModel(player.Data); if (syncingCount == 0) { var inGamePlayersDatas = playerManager.GetAllPlayerDataIncludingHost(); playerManager.SendPacketToAllPlayers(new SyncComplete(inGamePlayersDatas)); SimulatedWorld.OnAllPlayersSyncCompleted(); } }
public void StartServer(int port) { EventBasedNetListener listener = new EventBasedNetListener(); listener.ConnectionRequestEvent += OnConnectionRequest; listener.PeerConnectedEvent += OnPeerConnected; listener.PeerDisconnectedEvent += OnPeerDisconnected; listener.NetworkReceiveEvent += OnNetworkReceive; server = new NetManager(listener) { AutoRecycle = true, #if DEBUG SimulateLatency = true, SimulatePacketLoss = true, SimulationMinLatency = 50, SimulationMaxLatency = 100, #endif }; PlayerManager = new PlayerManager(); PacketProcessor = new NetPacketProcessor(); LiteNetLibUtils.RegisterAllPacketNestedTypes(PacketProcessor); LiteNetLibUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor); server.Start(port); SimulatedWorld.Initialize(); LocalPlayer.SetNetworkProvider(this); LocalPlayer.IsMasterClient = true; // TODO: Load saved player info here LocalPlayer.SetPlayerData(new PlayerData(PlayerManager.GetNextAvailablePlayerId(), new Float3(1.0f, 0.6846404f, 0.243137181f))); }
public void ProcessPacket(ILSShipData packet, NebulaConnection conn) { using (FactoryManager.EventFromServer.On()) { SimulatedWorld.OnILSShipUpdate(packet); } }
private void ConnectInternal() { LocalPlayer.TryLoadGalacticScale2(); clientSocket = new WebSocket(socketAddress); clientSocket.OnOpen += ClientSocket_OnOpen; clientSocket.OnClose += ClientSocket_OnClose; clientSocket.OnMessage += ClientSocket_OnMessage; PacketProcessor = new NetPacketProcessor(); #if DEBUG PacketProcessor.SimulateLatency = true; #endif PacketUtils.RegisterAllPacketNestedTypes(PacketProcessor); PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor); clientSocket.Connect(); SimulatedWorld.Initialize(); LocalPlayer.IsMasterClient = false; LocalPlayer.SetNetworkProvider(this); if (Config.Options.RememberLastIP) { // We've successfully connected, set connection as last ip, cutting out "ws://" and "/socket" Config.Options.LastIP = socketAddress.Substring(5, socketAddress.Length - 12); Config.SaveOptions(); } }
public static void OnLateUpdate_Postfix(UIStarmap __instance) { if (SimulatedWorld.Initialized) { SimulatedWorld.RenderPlayerNameTagsOnStarmap(__instance); } }
public static void GameTick_Postfix(long time, float dt) { if (SimulatedWorld.Initialized) { SimulatedWorld.OnDronesGameTick(time, dt); } }
public override void ProcessPacket(TrashSystemNewTrashCreatedPacket packet, NebulaConnection conn) { bool valid = true; if (IsHost) { Player player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToOtherPlayers(packet, player); } else { valid = false; } } if (valid) { int myId = SimulatedWorld.GenerateTrashOnPlayer(packet); //Check if myID is same as the ID from the host if (myId != packet.TrashId) { TrashManager.SwitchTrashWithIds(myId, packet.TrashId); } } }
public override void ProcessPacket(StationUI packet, NebulaConnection conn) { if (IsHost) { // if a user adds/removes a ship, drone or warper or changes max power input broadcast to everyone. if (StationUIManager.UpdateCooldown == 0 && (packet.SettingIndex == StationUI.EUISettings.MaxChargePower || packet.SettingIndex == StationUI.EUISettings.SetDroneCount || packet.SettingIndex == StationUI.EUISettings.SetShipCount || packet.SettingIndex == StationUI.EUISettings.SetWarperCount) ) { // this is the SendPacketToAllPlayers() logic but we need to set the mimic flag here. using (playerManager.GetConnectedPlayers(out var connectedPlayers)) { foreach (var kvp in connectedPlayers) { Player p = kvp.Value; packet.ShouldMimic = p.Connection == conn; p.SendPacket(packet); } } } else if (packet.SettingIndex == StationUI.EUISettings.AddOrRemoveItemFromStorageResponse) { // if someone adds or removes items by hand broadcast to every player on that planet Player player = playerManager.GetPlayer(conn); if (player != null) { playerManager.SendPacketToPlanet(packet, player.Data.LocalPlanetId); } } else if (StationUIManager.UpdateCooldown == 0 || !packet.IsStorageUI) { List <NebulaConnection> subscribers = StationUIManager.GetSubscribers(packet.PlanetId, packet.StationId, packet.StationGId); for (int i = 0; i < subscribers.Count; i++) { if (subscribers[i] != null) { /* * as we block the normal method for the client he must run it once he receives this packet. * but only the one issued the request should do it, we indicate this here */ packet.ShouldMimic = subscribers[i] == conn; subscribers[i].SendPacket(packet); } } } // always update values for host, but he does not need to rely on the mimic flag (infact its bad for him) packet.ShouldMimic = false; SimulatedWorld.OnStationUIChange(packet); } if (IsClient) { SimulatedWorld.OnStationUIChange(packet); } }
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(); }); } }); }
public void ProcessPacket(VegeMined packet, NebulaConnection conn) { Player player = playerManager.GetPlayer(conn); playerManager.SendPacketToOtherPlayers(packet, player); SimulatedWorld.MineVegetable(packet); }
public void ProcessPacket(HandshakeRequest packet, NebulaConnection conn) { Player player; if (!playerManager.PendingPlayers.TryGetValue(conn, out player)) { conn.Disconnect(DisconnectionReason.InvalidData); Log.Warn("WARNING: Player tried to handshake without being in the pending list"); return; } playerManager.PendingPlayers.Remove(conn); if (packet.ModVersion != Config.ModVersion.ToString()) { conn.Disconnect(DisconnectionReason.ModVersionMismatch); return; } if (packet.GameVersionSig != GameConfig.gameVersion.sig) { conn.Disconnect(DisconnectionReason.GameVersionMismatch); return; } SimulatedWorld.OnPlayerJoining(); //TODO: some validation of client cert / generating auth challenge for the client // Load old data of the client string clientCertHash = CryptoUtils.Hash(packet.ClientCert); if (playerManager.SavedPlayerData.ContainsKey(clientCertHash)) { player.LoadUserData(playerManager.SavedPlayerData[clientCertHash]); } else { playerManager.SavedPlayerData.Add(clientCertHash, 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 PlayerData pdata = player.Data.CreateCopyWithoutMechaData(); // Remove inventory from mecha data foreach (Player activePlayer in playerManager.GetConnectedPlayers()) { activePlayer.SendPacket(new PlayerJoining(pdata)); } // Add the new player to the list playerManager.SyncingPlayers.Add(conn, player); //Add current tech bonuses to the connecting player based on the Host's mecha player.Data.Mecha.TechBonuses = new PlayerTechBonuses(GameMain.mainPlayer.mecha); var gameDesc = GameMain.data.gameDesc; player.SendPacket(new HandshakeResponse(gameDesc.galaxyAlgo, gameDesc.galaxySeed, gameDesc.starCount, gameDesc.resourceMultiplier, player.Data)); }
public static void Update_Prefix() { if (!SimulatedWorld.Initialized || !SimulatedWorld.IsGameLoaded) { return; } SimulatedWorld.RenderPlayerNameTagsInGame(); }
public void ProcessPacket(TrashSystemNewTrashCreatedPacket packet, NebulaConnection conn) { int myId = SimulatedWorld.GenerateTrashOnPlayer(packet); //Check if myID is same as the ID from the host if (myId != packet.TrashId) { TrashManager.SwitchTrashWithIds(myId, packet.TrashId); } }
public void ProcessPacket(VegeMinedPacket packet, NebulaConnection conn) { if (GameMain.galaxy.PlanetById(packet.PlanetId)?.factory != null && GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.vegePool != null) { using (PlanetManager.EventFromServer.On()) { SimulatedWorld.OnVegetationMined(packet); } } }
public void ProcessPacket(GameStateUpdate packet, NebulaConnection conn) { GameState state = packet.State; // We offset the tick received to account for the current player ping long tickOffsetSinceSent = (long)System.Math.Round((conn.Ping / 2.0) / (GameMain.tickDeltaTime * 1000)); state.gameTick += tickOffsetSinceSent; SimulatedWorld.UpdateGameState(state); }
public static void FixedUpdate_Postfix(int ___frame) { if (___frame >= 11 && SimulatedWorld.Initialized) { SimulatedWorld.OnGameLoadCompleted(); if (!LocalPlayer.IsMasterClient) { MultiplayerClientSession.Instance.DisplayPingIndicator(); } } }
public void ProcessPacket(PlayerAnimationUpdate packet, NebulaConnection conn) { Player player = playerManager.GetPlayer(conn); if (player != null) { packet.PlayerId = player.Id; playerManager.SendPacketToOtherPlayers(packet, player); SimulatedWorld.UpdateRemotePlayerAnimation(packet); } }
public void PlayerDisconnected(NebulaConnection conn) { if (connectedPlayers.TryGetValue(conn, out Player player)) { SendPacketToOtherPlayers(new PlayerDisconnected(player.Id), player); connectedPlayers.Remove(conn); availablePlayerIds.Enqueue(player.Id); SimulatedWorld.DestroyRemotePlayerModel(player.Id); } // TODO: Should probably also handle playing that disconnect during "pending" or "syncing" steps. }
public void ProcessPacket(GameStateUpdate packet, NebulaConnection conn) { GameState state = packet.State; // We offset the tick received to account for the time it took to receive the packet long timeOffset = TimeUtils.CurrentUnixTimestampMilliseconds() - packet.State.timestamp; long tickOffsetSinceSent = (long)System.Math.Round(timeOffset / (GameMain.tickDeltaTime * 1000)); state.gameTick += tickOffsetSinceSent; SimulatedWorld.UpdateGameState(state); }