/// <summary> /// 玩家, 离开房间 /// </summary> public NetLeftRoomResult LeftRoom(ulong roleUid, NetworkingPlayer networkingPlayer) { NetworkingPlayer player; if (playerDict.TryGetValue(roleUid, out player)) { if (networkingPlayer != null && networkingPlayer.NetworkId != player.NetworkId) { // 不是同一个终端 return(NetLeftRoomResult.Failed_NoSameSocket); } playerDict.Remove(roleUid); // 广播玩家离开 BMSByte data = ObjectMapper.BMSByte(roleUid); Binary sendframe = new Binary(Time.Timestep, false, data, Receivers.Target, MessageGroupIds.ROOM, false, RouterIds.ROOM_LEFT_ROOM, roomId); Send(sendframe, true); OnPlayerLeftRoom(roleUid, networkingPlayer); return(NetLeftRoomResult.Successed); } // 不存在该玩家 return(NetLeftRoomResult.Failed_RoomNoPlayer); }
/// <summary> /// 创建房间 /// </summary> public bool CreateRoom(NetRoomInfo roomInfo, NetworkingPlayer player = null) { if (roomDict.ContainsKey(roomInfo.roomUid)) { // 创建房间失败, 房间 已经存在 string error = string.Format("创建房间失败, 房间ID={0}, 已经存在", roomInfo.roomUid); OnCreateRoomFailed(roomInfo.roomUid, error); if (player != null) { BMSByte data = ObjectMapper.BMSByte(false, roomInfo.roomUid, error); Binary frame = new Binary(Socket.Time.Timestep, false, data, Receivers.Target, MessageGroupIds.Lobby, false, RouterIds.LOBBY_CREATE_ROOM); Send(player, frame, true); } return(false); } // 创建房间成功 NetRoomServer room = new NetRoomServer(this, roomInfo); roomDict.Add(room.roomId, room); OnCreateRoomSuccessed(room.roomId); if (player != null) { BMSByte data = ObjectMapper.BMSByte(true, roomInfo.roomUid, string.Empty); Binary frame = new Binary(Socket.Time.Timestep, false, data, Receivers.Target, MessageGroupIds.Lobby, false, RouterIds.LOBBY_CREATE_ROOM); Send(player, frame, true); } return(true); }
public void LeftWatchRoom(ulong roomUid, NetworkingPlayer player = null, bool isDisconnected = false) { NetLeftRoomResult ret; NetRoomServer room; if (roomDict.TryGetValue(roomUid, out room)) { room.LeftWatchRoom(player); ret = NetLeftRoomResult.Successed; } else { ret = NetLeftRoomResult.Failed_NoRoom; } OnPlayerLeftWatchRoom(roomUid, player, ret); if (isDisconnected && player != null) { BMSByte data = ObjectMapper.BMSByte(roomUid, (int)ret); Binary sendframe = new Binary(Socket.Time.Timestep, false, data, Receivers.Target, MessageGroupIds.Lobby, false, RouterIds.LOBBY_LEFT_WATCH_ROOM); Send(player, sendframe, true); } }
/// <summary> /// 加入观看房间 /// </summary> private void JoinWatchRoom(NetworkingPlayer player, Binary frame) { // 房间UID ulong roomUid = frame.StreamData.GetBasicType <ulong>(); NetJoinRoomResult ret; NetRoomServer room; if (!roomDict.TryGetValue(roomUid, out room)) { // 失败 不存在该房间 ret = NetJoinRoomResult.Failed_NoRoom; } else { room.JoinWatchRoom(player); ret = NetJoinRoomResult.Successed; player.lastRoomUid = roomUid; player.lastRoleUid = 0; } OnPlayerJoinWatchRoom(roomUid, player, ret); BMSByte data = ObjectMapper.BMSByte(roomUid, (int)ret); Binary sendframe = new Binary(Socket.Time.Timestep, false, data, Receivers.Target, MessageGroupIds.Lobby, false, RouterIds.LOBBY_JOIN_WATCH_ROOM); Send(player, sendframe, true); }
/// <summary> /// 玩家, 加入房间 /// </summary> public NetJoinRoomResult JoinRoom(ulong roleUid, NetworkingPlayer networkingPlayer, Binary frame) { NetJoinRoomResult ret; if (playerDict.ContainsKey(roleUid)) { playerDict.Remove(roleUid); playerDict.Add(roleUid, networkingPlayer); ret = NetJoinRoomResult.Existed; } else { playerDict.Add(roleUid, networkingPlayer); ret = NetJoinRoomResult.Successed; } networkingPlayer.lastRoleUid = roleUid; // 广播玩家加入 BMSByte data = ObjectMapper.BMSByte(roleUid); Binary sendframe = new Binary(Time.Timestep, false, data, Receivers.Target, MessageGroupIds.ROOM, false, RouterIds.ROOM_JOIN_ROOM, roomId); Send(sendframe, true); OnPlayerJoinRoom(roleUid, networkingPlayer); OnPlayerJoined(networkingPlayer); return(ret); }
/// <summary> /// 创建房间 /// </summary> public void CreateRoom() { BMSByte data = ObjectMapper.BMSByte(roomInfo.roomUid, roomInfo.stageId); Binary frame = new Binary(Socket.Time.Timestep, false, data, Receivers.Server, MessageGroupIds.Lobby, false, RouterIds.LOBBY_CREATE_ROOM); Send(frame, true); }
/// <summary> /// 离开观看房间 /// </summary> public void LeftWatchRoom(int roomUid) { BMSByte data = ObjectMapper.BMSByte(roomUid); Binary frame = new Binary(Socket.Time.Timestep, false, data, Receivers.Server, MessageGroupIds.Lobby, false, RouterIds.LOBBY_LEFT_WATCH_ROOM); Send(frame, true); }
private Binary SendBinary(NetWorker networker) { BMSByte data = ObjectMapper.BMSByte(MESSAGE); ulong timestep = (ulong)(DateTime.UtcNow - start).TotalMilliseconds; return(new Binary(timestep, networker is TCPClient, data, Receivers.Target, 17931, networker is BaseTCP)); }
/// <summary> /// Get an object from cache /// </summary> /// <param name="key">The name variable used for storing the desired object</param> /// <returns>The string data at the desired key or null</returns> /// <remarks> /// Allows a client (or the server) to get a value from the Cache, the value is read directly from the server. /// A callback must be specified, this is because the code has to be executed after a moment when the response from the server /// is received. Request can be done like this: /// <code> /// void getServerDescription(){ /// Cache.Request<string>("server_description", delegate (object response){ /// Debug.Log(((string) response)); /// }); /// } /// </code> /// The Cache only supports Forge's supported data Types, you can find a list of supported data Types in the NetSync documentation... /// </remarks> public void Request <T>(string key, Action <object> callback) { if (callback == null) { throw new Exception("A callback is needed when requesting data from the server"); } if (Socket.IsServer) { callback(Get <T>(key)); return; } responseHooks.Add(responseHookIncrementer, callback); byte targetType = byte.MaxValue; foreach (KeyValuePair <byte, Type> kv in typeMap) { if (typeof(T) == kv.Value) { targetType = kv.Key; break; } } if (targetType == byte.MaxValue) { throw new Exception("Invalid type specified"); } BMSByte data = ObjectMapper.BMSByte(targetType, responseHookIncrementer, key); Binary sendFrame = new Binary(Socket.Time.Timestep, Socket is TCPClient, data, Receivers.Server, MessageGroupIds.CACHE, Socket is BaseTCP); #if STEAMWORKS if (Socket is SteamP2PClient) { ((SteamP2PClient)Socket).Send(sendFrame, true); } else if (Socket is BaseTCP) #elif FACEPUNCH_STEAMWORKS if (Socket is FacepunchP2PClient) { ((FacepunchP2PClient)Socket).Send(sendFrame, true); } else if (Socket is BaseTCP) #else if (Socket is BaseTCP) #endif { ((TCPClient)Socket).Send(sendFrame); } else { ((UDPClient)Socket).Send(sendFrame, true); } responseHookIncrementer++; }
public void BMSByteTest() { byte b = 1; for (int i = 0; i < 10000; i++) { BMSByte data = ObjectMapper.BMSByte(b, b, b, b, b, b, b, b, b, b, b); } }
/// <summary> /// Called automatically when a new player is accepted and sends the player /// the currently loaded scene indexes for the client to load /// </summary> /// <param name="player">The player that was just accepted</param> /// <param name="sender">The sending <see cref="NetWorker"/></param> protected virtual void PlayerAcceptedSceneSetup(NetworkingPlayer player, NetWorker sender) { BMSByte data = ObjectMapper.BMSByte(loadedScenes.Count); // Go through all the loaded scene indexes and send them to the connecting player for (int i = 0; i < loadedScenes.Count; i++) { ObjectMapper.Instance.MapBytes(data, loadedScenes[i]); } Binary frame = new Binary(sender.Time.Timestep, false, data, Receivers.Target, MessageGroupIds.VIEW_INITIALIZE, sender is BaseTCP); SendFrame(sender, frame, player); }
public void AcceptChallenge(NetWorker networker, BMSByte challenge, Action <BMSByte> authServerAction, Action rejectServerAction) { Server.AuthStatus status = challenge.GetBasicType <Server.AuthStatus>(); switch (status) { case Server.AuthStatus.Available: List <uint> memberIds = new List <uint>(); /*foreach (Friend f in ourLobby.Members) * { * memberIds.Add(f.Id.AccountId); * }*/ BMSByte response = ObjectMapper.BMSByte(SteamClient.SteamId.AccountId); BinaryFormatter binFor = new BinaryFormatter(); MemoryStream memStream = new MemoryStream(); binFor.Serialize(memStream, memberIds); //response.Append(ObjectMapper.BMSByte(memberIds.ToArray())); response.Append(ObjectMapper.BMSByte(memStream.ToArray())); authServerAction(response); memStream.Close(); return; case Server.AuthStatus.Checking: authServerAction(ObjectMapper.BMSByte(SteamClient.SteamId.AccountId)); return; case Server.AuthStatus.Closed: rejectServerAction(); return; } /* * BMSByte by = new BMSByte(); * var binFormatter = new BinaryFormatter(); * var mStream = new MemoryStream(); * binFormatter.Serialize(mStream, allowedSteamIDs); * * var data = ObjectMapper.BMSByte(mStream.ToArray()); * * authServerAction(data); */ }
/// <summary> /// Callback for when a Scene has been unloaded /// </summary> /// <param name="scene"></param> public virtual void SceneUnloaded(Scene scene) { // The NetworkManager has not yet been initialized with a Networker. if (!initialized) { return; } loadedScenes.Remove(scene.buildIndex); // Send buildindex and 2 refering to BMSByte data = ObjectMapper.BMSByte(scene.buildIndex, UnloadSceneCommand); Binary frame = new Binary(Networker.Time.Timestep, false, data, Networker is IServer ? Receivers.All : Receivers.Server, MessageGroupIds.VIEW_CHANGE, false); // Send the binary frame to either the server or the clients SendFrame(Networker, frame); }
private void BinaryMessageReceived(NetworkingPlayer player, Binary frame, NetWorker sender) { Loger.Log(frame.StreamData.Size + " " + frame.StreamData.StartPointer); string identifier = frame.StreamData.GetBasicType <string>(); string content = frame.StreamData.GetBasicType <string>(); string message = "NetworkId:" + player.NetworkId + " " + player.Name + " " + identifier + " " + content; Loger.Log(message); object[] args = new object[] { identifier, content }; BMSByte data = ObjectMapper.BMSByte(args); Binary subFrame = new Binary(server.Time.Timestep, false, data, Receivers.All, GROUPID_BINARY, false); server.Send(subFrame, true); }
/// <summary> /// Called automatically when a new player is accepted and sends the player /// the currently loaded scene indexes for the client to load /// </summary> /// <param name="player">The player that was just accepted</param> private void PlayerAcceptedSceneSetup(NetworkingPlayer player, NetWorker sender) { BMSByte data = ObjectMapper.BMSByte(loadedScenes.Count); // Go through all the loaded scene indexes and send them to the connecting player for (int i = 0; i < loadedScenes.Count; i++) { ObjectMapper.Instance.MapBytes(data, loadedScenes[i]); } Binary frame = new Binary(sender.Time.Timestep, false, data, Receivers.Target, MessageGroupIds.VIEW_INITIALIZE, sender is BaseTCP); SendFrame(sender, frame, player); /* * /// send frame data * _frameData.BMSData = Convert.ToBase64String(frame.GetData()); * _frameData.GroupID = MessageGroupIds.VIEW_INITIALIZE; * PTK.ArenaObservable.FrameData[] objs = { _frameData }; * string json = _frameData.ToJson<PTK.ArenaObservable.FrameData>(objs, false); * PTK.Ansuz.Instance.PublishToTopic("arena/frameData/all", json, 0); */ }
public virtual void SceneLoaded(Scene scene, LoadSceneMode mode) { // The NetworkManager has not yet been initialized with a Networker. if (!initialized) { return; } // If we are loading a completely new scene then we will need // to clear out all the old objects that were stored as they // are no longer needed if (mode != LoadSceneMode.Additive) { pendingObjects.Clear(); pendingNetworkObjects.Clear(); loadedScenes.Clear(); } lock (NetworkObject.PendingCreatesLock) { loadingScenes.Remove(scene.buildIndex); } loadedScenes.Add(scene.buildIndex); if (networkSceneLoaded != null) { networkSceneLoaded(scene, mode); } BMSByte data = ObjectMapper.BMSByte(scene.buildIndex, (int)mode); Binary frame = new Binary(Networker.Time.Timestep, false, data, Networker is IServer ? Receivers.All : Receivers.Server, MessageGroupIds.VIEW_CHANGE, Networker is BaseTCP); // Send the binary frame to either the server or the clients SendFrame(Networker, frame); // Go through all of the current NetworkBehaviors in the order that Unity finds them in // and associate them with the id that the network will be giving them as a lookup int currentAttachCode = 1; var behaviors = FindObjectsOfType <NetworkBehavior>().Where(b => !b.Initialized) .OrderBy(b => b.GetType().ToString()) .OrderBy(b => b.name) .OrderBy(b => Vector3.Distance(Vector3.zero, b.transform.position)) .ToList(); if (behaviors.Count == 0) { if (Networker is IClient) { if (loadingScenes.Count > 0) { NetworkObject.Flush(Networker, loadingScenes, CreatePendingObjects); } else { NetworkObject.Flush(Networker, loadingScenes); if (pendingObjects.Count == 0) { Networker.objectCreated -= CreatePendingObjects; } } } return; } foreach (NetworkBehavior behavior in behaviors) { behavior.TempAttachCode = scene.buildIndex << 16; behavior.TempAttachCode += currentAttachCode++; behavior.TempAttachCode = -behavior.TempAttachCode; } if (Networker is IClient) { // This would occur if objects in the additive scene arrives at the same time as the // "single" scene and were flushed. if (mode == LoadSceneMode.Additive && pendingNetworkObjects.Count > 0) { NetworkObject foundNetworkObject; for (int i = 0; i < behaviors.Count; i++) { if (pendingNetworkObjects.TryGetValue(behaviors[i].TempAttachCode, out foundNetworkObject)) { behaviors[i].Initialize(foundNetworkObject); pendingNetworkObjects.Remove(behaviors[i].TempAttachCode); behaviors.RemoveAt(i--); } } } foreach (NetworkBehavior behavior in behaviors) { pendingObjects.Add(behavior.TempAttachCode, behavior); } NetworkObject.Flush(Networker, loadingScenes, CreatePendingObjects); if (pendingObjects.Count == 0 && loadingScenes.Count == 0) { Networker.objectCreated -= CreatePendingObjects; } else if (pendingObjects.Count != 0 && loadingScenes.Count == 0) { // Pending network behavior list is not empty when there are no more scenes to load. // Probably network behaviours that were placed in the scene have already been destroyed on the server and other clients! List <GameObject> objetsToDestroy = new List <GameObject>(pendingObjects.Count); foreach (var behavior in pendingObjects.Values) { var gameObject = ((NetworkBehavior)behavior).gameObject; if (!objetsToDestroy.Contains(gameObject)) { objetsToDestroy.Add(gameObject); } } pendingObjects.Clear(); foreach (var o in objetsToDestroy) { Destroy(o); } objetsToDestroy.Clear(); } } else { // Go through all of the pending NetworkBehavior objects and initialize them on the network foreach (INetworkBehavior behavior in behaviors) { behavior.Initialize(Networker); } } }
private void SceneReady(Scene scene, LoadSceneMode mode) { // If we are loading a completely new scene then we will need // to clear out all the old objects that were stored as they // are no longer needed if (mode != LoadSceneMode.Additive) { pendingObjects.Clear(); pendingNetworkObjects.Clear(); loadedScenes.Clear(); } loadedScenes.Add(scene.buildIndex); if (networkSceneLoaded != null) { networkSceneLoaded(scene, mode); } BMSByte data = ObjectMapper.BMSByte(scene.buildIndex, (int)mode); try{ Binary frame = new Binary(Networker.Time.Timestep, false, data, Networker is IServer ? Receivers.All : Receivers.Server, MessageGroupIds.VIEW_CHANGE, Networker is BaseTCP); // Send the binary frame to either the server or the clients SendFrame(Networker, frame); } catch (Exception e) {} // Go through all of the current NetworkBehaviors in the order that Unity finds them in // and associate them with the id that the network will be giving them as a lookup int currentAttachCode = 1; var behaviors = FindObjectsOfType <NetworkBehavior>().Where(b => !b.Initialized) .OrderBy(b => b.GetType().ToString()) .OrderBy(b => b.name) .OrderBy(b => Vector3.Distance(Vector3.zero, b.transform.position)) .ToList(); if (behaviors.Count == 0) { if (Networker is IClient) { NetworkObject.Flush(Networker); } return; } foreach (NetworkBehavior behavior in behaviors) { behavior.TempAttachCode = scene.buildIndex << 16; behavior.TempAttachCode += currentAttachCode++; behavior.TempAttachCode = -behavior.TempAttachCode; } if (Networker is IClient) { NetworkObject.Flush(Networker); NetworkObject foundNetworkObject; for (int i = 0; i < behaviors.Count; i++) { if (pendingNetworkObjects.TryGetValue(behaviors[i].TempAttachCode, out foundNetworkObject)) { behaviors[i].Initialize(foundNetworkObject); pendingNetworkObjects.Remove(behaviors[i].TempAttachCode); behaviors.RemoveAt(i--); } } if (behaviors.Count == 0) { return; } } if (Networker is IServer) { // Go through all of the pending NetworkBehavior objects and initialize them on the network foreach (INetworkBehavior behavior in behaviors) { behavior.Initialize(Networker); } return; } foreach (NetworkBehavior behavior in behaviors) { pendingObjects.Add(behavior.TempAttachCode, behavior); } if (pendingNetworkObjects.Count == 0) { Networker.objectCreated -= CreatePendingObjects; } }
/// <summary> /// Called when the network as interpreted that a cache message has been sent from the server /// </summary> /// <param name="player">The server</param> /// <param name="frame">The data that was received</param> private void BinaryMessageReceived(NetworkingPlayer player, Binary frame, NetWorker sender) { if (frame.GroupId != MessageGroupIds.CACHE) { return; } if (sender is IServer) { byte type = ObjectMapper.Instance.Map <byte>(frame.StreamData); int responseHookId = ObjectMapper.Instance.Map <int>(frame.StreamData); string key = ObjectMapper.Instance.Map <string>(frame.StreamData); object obj = Get(key); // TODO: Let the client know it is null if (obj == null) { return; } BMSByte data = ObjectMapper.BMSByte(type, responseHookId, obj); Binary sendFrame = new Binary(sender.Time.Timestep, sender is TCPClient, data, Receivers.Target, MessageGroupIds.CACHE, sender is BaseTCP); if (sender is BaseTCP) { ((TCPServer)sender).Send(player.TcpClientHandle, sendFrame); } else { ((UDPServer)sender).Send(player, sendFrame, true); } } else { byte type = ObjectMapper.Instance.Map <byte>(frame.StreamData); int responseHookId = ObjectMapper.Instance.Map <int>(frame.StreamData); object obj = null; if (typeMap[type] == typeof(string)) { obj = ObjectMapper.Instance.Map <string>(frame.StreamData); } /*else if (typeMap[type] == typeof(Vector2)) * obj = ObjectMapper.Map<Vector2>(stream); * else if (typeMap[type] == typeof(Vector3)) * obj = ObjectMapper.Map<Vector3>(stream); * else if (typeMap[type] == typeof(Vector4)) * obj = ObjectMapper.Map<Vector4>(stream); * else if (typeMap[type] == typeof(Color)) * obj = ObjectMapper.Map<Color>(stream); * else if (typeMap[type] == typeof(Quaternion)) * obj = ObjectMapper.Map<Quaternion>(stream);*/ else { obj = ObjectMapper.Instance.Map(typeMap[type], frame.StreamData); } if (responseHooks.ContainsKey(responseHookId)) { responseHooks[responseHookId](obj); responseHooks.Remove(responseHookId); } } }
public void IssueChallenge(NetWorker networker, NetworkingPlayer player, System.Action <NetworkingPlayer, BMSByte> issueChallengeAction, System.Action <NetworkingPlayer> skipAuthAction) { issueChallengeAction(player, ObjectMapper.BMSByte(status)); }