/// <summary> /// Register protocol related network messages handlers. /// </summary> void RegisterProtocolMessagesHandlers() { netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.HandshakeMessage msg) => { HandleHandshake(sender, msg); }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.HeartbeatMessage msg) => { var message = new Messages.HeartbeatResponseMessage(); message.clientClock = msg.clientClock; message.clock = GetNetworkClock(); BroadcastMessage(message, Steamworks.EP2PSend.k_EP2PSendReliable); }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.HeartbeatResponseMessage msg) => { ping = (uint)(GetNetworkClock() - msg.clientClock); // TODO: Some smart lag compensation. remoteClock = msg.clock; timeSinceLastHeartbeat = 0.0f; }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.DisconnectMessage msg) => { HandleDisconnect(false); }); }
/// <summary> /// Register protocol related network messages handlers. /// </summary> void RegisterProtocolMessagesHandlers() { netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.HandshakeMessage msg) => { HandleHandshake(sender, msg); }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.HeartbeatMessage msg) => { var message = new Messages.HeartbeatResponseMessage(); message.clientClock = msg.clientClock; message.clock = GetNetworkClock(); BroadcastMessage(message, Steamworks.EP2PSend.k_EP2PSendReliable); }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.HeartbeatResponseMessage msg) => { ping = (uint)(GetNetworkClock() - msg.clientClock); // TODO: Some smart lag compensation. remoteClock = msg.clock; timeSinceLastHeartbeat = 0.0f; }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PhoneMessage msg) => { Game.PhoneManager.Instance.PhoneCall(msg.topic, msg.timesToRing); }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.DartSyncMessage msg) => { Game.MapManager.Instance.SyncDartsHandler(msg.darts); }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.DisconnectMessage msg) => { HandleDisconnect(GetPlayerIDBySteamID(sender), false); }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.ConnectedPlayersMessage msg) => { int i = 0; foreach (int newPlayerID in msg.playerIDs) { Steamworks.CSteamID localSteamID = Steamworks.SteamUser.GetSteamID(); Steamworks.CSteamID newPlayerSteamID = new Steamworks.CSteamID(msg.steamIDs[i]); // If player is not host or local player, setup new player. if (newPlayerSteamID != hostSteamID && newPlayerSteamID != localSteamID) { players.Add(newPlayerID, new NetPlayer(this, netWorld, newPlayerSteamID)); players[newPlayerID].Spawn(); Logger.Debug("Setup new player at ID: " + newPlayerID); } i++; } }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PlayerJoinMessage msg) => { if (NetWorld.Instance.playerIsLoading) { if (msg.steamID == Steamworks.SteamUser.GetSteamID().m_SteamID&& localPlayerID == -1) { players.Add(msg.playerID, new NetLocalPlayer(this, netWorld, new Steamworks.CSteamID(msg.steamID))); localPlayerID = msg.playerID; Logger.Debug("Setup local player as ID: " + msg.playerID); } else { Logger.Debug("Ignored connecting player as curent player is still loading!"); } return; } Steamworks.CSteamID newPlayerSteamID = new Steamworks.CSteamID(msg.steamID); if (newPlayerSteamID != hostSteamID && newPlayerSteamID != GetLocalPlayer().SteamId) { players.Add(msg.playerID, new NetPlayer(this, netWorld, newPlayerSteamID)); players[msg.playerID].Spawn(); MessagesList.AddMessage($"Player {players[msg.playerID].GetName()} joined.", MessageSeverity.Info); Logger.Debug("New player connected at ID: " + msg.playerID); } }); netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PlayerLeaveMessage msg) => { if (NetWorld.Instance.playerIsLoading) { Logger.Debug("Ignored connecting player as curent player is still loading!"); return; } MessagesList.AddMessage($"Player {players[msg.playerID].GetName()} disconnected. ({msg.reason})", MessageSeverity.Info); CleanupPlayer(msg.playerID); }); }
public NetManager() { this.netManagerCreationTime = DateTime.UtcNow; netWorld = new NetWorld(this); // Setup local player. players[0] = new NetLocalPlayer(this, netWorld, Steamworks.SteamUser.GetSteamID()); p2pSessionRequestCallback = Steamworks.Callback <Steamworks.P2PSessionRequest_t> .Create((Steamworks.P2PSessionRequest_t result) => { if (!Steamworks.SteamNetworking.AcceptP2PSessionWithUser(result.m_steamIDRemote)) { Logger.Log("Accepted p2p session with " + result.m_steamIDRemote.ToString()); } }); gameLobbyJoinRequestedCallback = Steamworks.Callback <Steamworks.GameLobbyJoinRequested_t> .Create(OnGameLobbyJoinRequested); lobbyCreatedCallResult = new Steamworks.CallResult <Steamworks.LobbyCreated_t>((Steamworks.LobbyCreated_t result, bool ioFailure) => { if (result.m_eResult != Steamworks.EResult.k_EResultOK) { Logger.Log("Oh my f*****g god i failed to create a lobby for you. Please forgive me. (result: " + result.m_eResult + ")"); MPGUI.Instance.ShowMessageBox("Failed to create lobby due to steam error.\n" + result.m_eResult, () => { MPController.Instance.LoadLevel("MainMenu"); }); return; } Logger.Log("Hey you! I have lobby id for you! " + result.m_ulSteamIDLobby); mode = Mode.Host; state = State.Playing; currentLobbyId = new Steamworks.CSteamID(result.m_ulSteamIDLobby); netWorld.RegisterPickupables(); }); lobbyEnterCallResult = new Steamworks.CallResult <Steamworks.LobbyEnter_t>((Steamworks.LobbyEnter_t result, bool ioFailure) => { if (result.m_EChatRoomEnterResponse != (uint)Steamworks.EChatRoomEnterResponse.k_EChatRoomEnterResponseSuccess) { Logger.Log("Oh my f*****g god i failed to join the lobby for you. Please forgive me. (reponse: " + result.m_EChatRoomEnterResponse + ")"); players[1] = null; return; } Logger.Log("Oh hello! " + result.m_ulSteamIDLobby); mode = Mode.Player; state = State.LoadingGameWorld; currentLobbyId = new Steamworks.CSteamID(result.m_ulSteamIDLobby); SendHandshake(); }); // TODO: Move message handlers to some class. BindMessageHandler((Steamworks.CSteamID sender, Messages.HandshakeMessage msg) => { remoteClock = msg.clock; HandleHandshake(sender, msg); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.PlayerSyncMessage msg) => { if (players[1] == null) { Logger.Log("Received synchronization packet but no remote player is currently connected."); return; } players[1].HandleSynchronize(msg); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.HeartbeatMessage msg) => { var message = new Messages.HeartbeatResponseMessage(); message.clientClock = msg.clientClock; message.clock = GetNetworkClock(); BroadcastMessage(message, Steamworks.EP2PSend.k_EP2PSendReliable); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.HeartbeatResponseMessage msg) => { ping = (uint)(GetNetworkClock() - msg.clientClock); // TODO: Some smart lag compensation. remoteClock = msg.clock; timeSinceLastHeartbeat = 0.0f; }); BindMessageHandler((Steamworks.CSteamID sender, Messages.DisconnectMessage msg) => { HandleDisconnect(false); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.OpenDoorsMessage msg) => { NetPlayer player = players[1]; // 1.5 is a length of the ray used to check interaction with doors in game scripts. Vector3 interactionPosition = player.GetPosition() + player.GetRotation() * Vector3.forward * 1.5f; Game.Objects.GameDoor doors = Game.GameDoorsManager.Instance.FindGameDoors(interactionPosition); if (doors == null) { Logger.Log($"Player tried to open doors however he is not close to any: {interactionPosition}."); return; } doors.Open(msg.open); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.FullWorldSyncMessage msg) => { netWorld.HandleFullWorldSync(msg); // Now spawn player. if (players[1] != null) { players[1].Spawn(); } // World loaded we are playing! state = State.Playing; }); BindMessageHandler((Steamworks.CSteamID sender, Messages.AskForWorldStateMessage msg) => { var msgF = new Messages.FullWorldSyncMessage(); netWorld.WriteFullWorldSync(msgF); BroadcastMessage(msgF, Steamworks.EP2PSend.k_EP2PSendReliable); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.VehicleEnterMessage msg) => { NetPlayer player = players[1]; if (player == null) { return; } NetVehicle vehicle = netWorld.GetVehicle(msg.vehicleId); if (vehicle == null) { Logger.Log("Player " + player.SteamId + " tried to enter vehicle " + msg.vehicleId + " but there is no vehicle with such id."); return; } player.EnterVehicle(vehicle, msg.passenger); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.VehicleLeaveMessage msg) => { NetPlayer player = players[1]; if (player == null) { return; } player.LeaveVehicle(); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.VehicleSyncMessage msg) => { NetPlayer player = players[1]; if (player == null) { return; } player.HandleVehicleSync(msg); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.PickupObjectMessage msg) => { NetPlayer player = players[1]; if (player == null) { return; } player.PickupObject(msg.netId); }); BindMessageHandler((Steamworks.CSteamID sender, Messages.ReleaseObjectMessage msg) => { NetPlayer player = players[1]; if (player == null) { return; } player.ReleaseObject(msg.drop); }); }