public void OnNeutronRegister(NeutronPlayer player, bool isServer, Scene scene, MatchmakingMode mode, INeutronMatchmaking matchmaking, Neutron neutron) { if (!_isOriginalObject) { return; } #region Prevent Being Instantiated if (_hasMap) { if (!(mode == _matchmakingMode)) { return; } if (matchmaking.Get.ContainsKey(_mapKey)) { string mapName = matchmaking.Get[_mapKey].ToObject <string>(); if (!(mapName == _mapName)) { return; } else /*continue;*/ } { } else { LogHelper.Info($"This scene object({_mapName} - {matchmaking.Name}) is not linked to a map, it will be instantiated in all scenes of the specified matchmaking."); } }
//* sabe deus. public static bool RemovePlayerFromServer(NeutronPlayer player) { bool tryRemove = Neutron.Server.PlayersBySocket.TryRemove(player.TcpClient, out NeutronPlayer __) && Neutron.Server.PlayersById.TryRemove(player.Id, out NeutronPlayer _); if (tryRemove) { Neutron.Server._pooledIds.Push(player.Id); string addr = player.StateObject.TcpRemoteEndPoint.Address.ToString(); if (Neutron.Server.RegisteredConnectionsByIp.TryGetValue(addr, out int value)) { Neutron.Server.RegisteredConnectionsByIp[addr] = --value; } MatchmakingHelper.Destroy(player); PlayerHelper.Disconnect(player, "Exited"); if (player.IsInRoom()) { INeutronMatchmaking matchmaking = player.Matchmaking; if (matchmaking != null) { //* Sai da sala. if (matchmaking.Remove(player)) { MatchmakingHelper.Internal.Leave(player, MatchmakingMode.Room); } //* Sai do canal. if (player.IsInChannel()) { matchmaking = player.Matchmaking; if (matchmaking.Remove(player)) { MatchmakingHelper.Internal.Leave(player, MatchmakingMode.Channel); } } } else { LogHelper.Error("Leave: Matchmaking not found!"); } } else { //* Sai do canal. INeutronMatchmaking matchmaking = player.Matchmaking; if (matchmaking != null) { if (matchmaking.Remove(player)) { MatchmakingHelper.Internal.Leave(player, MatchmakingMode.Channel); } } } Interlocked.Decrement(ref Neutron.Server._playerCount); } else { LogHelper.Error("Failed to remove player from server!"); } return(tryRemove); }
protected async void HandshakeHandler(NeutronPlayer player, double clientTime, Authentication authentication) { if (authentication.Pass.Decrypt(out string phrase)) { authentication = new Authentication(authentication.User, phrase, false); try { if (await OnAuthentication.Invoke(player, authentication)) //* First packet { using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) //* Second First packet { NeutronStream.IWriter writer = stream.Writer; writer.WritePacket((byte)Packet.Handshake); writer.Write(LocalTime); writer.Write(clientTime); writer.Write(player.StateObject.UdpLocalEndPoint.Port); writer.WriteWithInteger(player); player.Write(writer); } OnPlayerConnected?.Invoke(player); //* Three packet } } catch (Exception ex) // Tasks manual catch exception. { LogHelper.Stacktrace(ex); } } else if (!LogHelper.Error("Auth decrypt failed!")) { DisconnectHandler(player); } }
private void UdpApmReceive(NeutronPlayer player) { if (player.TokenSource.Token.IsCancellationRequested) { return; //* Check if the token is cancelled. } SocketHelper.BeginReadBytes(player.UdpClient, player.StateObject, (ar) => { EndPoint remoteEp = player.StateObject.NonAllocEndPoint; //* Get the remote end point, prevent GC pressure/allocations. int bytesRead = SocketHelper.EndReadBytes(player.UdpClient, ref remoteEp, ar); //* End the read. if (!player.StateObject.UdpIsReady()) { player.StateObject.UdpRemoteEndPoint = (IPEndPoint)remoteEp; //* Set the remote end point. } if (bytesRead > 0) { player.StateObject.SlicedDatagram = new byte[bytesRead]; //* Create the datagram. Buffer.BlockCopy(player.StateObject.ReceivedDatagram, 0, player.StateObject.SlicedDatagram, 0, bytesRead); //* Copy the received bytes to the datagram. CreateUdpPacket(player); //* Create the packet. } if (!NeutronModule.IsUnityThread) { UdpApmReceive(player); //* Receive again. } }); }
protected void ChatHandler(NeutronPlayer player, ChatMode packet, MatchmakingTo matchmakingTo, int viewId, string message) { if (OnMessageReceived.Invoke(player, message)) { using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = stream.Writer; writer.WritePacket((byte)Packet.Chat); writer.Write(message); if (packet == ChatMode.Global) { player.Write(writer, TargetTo.All, matchmakingTo, Protocol.Tcp); } else if (packet == ChatMode.Private) { if (MatchmakingHelper.Server.GetPlayer(viewId, out NeutronPlayer playerFound)) { playerFound.Write(player, writer, TargetTo.Me, MatchmakingTo.Me, Protocol.Tcp); } else { player.Error(Packet.Chat, "Player not found!", ErrorMessage.PLAYER_NOT_FOUND); } } } } }
public NeutronPacket(byte[] buffer, NeutronPlayer owner, NeutronPlayer sender, Protocol protocol) { Buffer = buffer; Owner = owner; Sender = sender; Protocol = protocol; }
public NeutronCache(int id, byte[] buffer, NeutronPlayer owner, CachedPacket packet, CacheMode cacheMode) { Id = id; Buffer = buffer; Owner = owner; Packet = packet; CacheMode = cacheMode; }
protected void DisconnectHandler(NeutronPlayer player) { using (player) //* Libera os recursos não gerenciados do jogador desconectado. { if (SocketHelper.RemovePlayerFromServer(player)) { OnPlayerDisconnected?.Invoke(player); } } }
protected override void OnPlayerConnected(NeutronPlayer player, bool isMine, Neutron neutron) { base.OnPlayerConnected(player, isMine, neutron); { if (isMine) { neutron.JoinChannel(0); } } }
public static NeutronPacket PollPacket(byte[] buffer, NeutronPlayer owner, NeutronPlayer sender, Protocol protocol) { NeutronPacket neutronPacket = Neutron.PooledNetworkPackets.Pull(); neutronPacket.Buffer = buffer; neutronPacket.Owner = owner; neutronPacket.Sender = sender; neutronPacket.Protocol = protocol; return(neutronPacket); }
private void ProcessMessage(NeutronPlayer player, string message) { NeutronSchedule.ScheduleTask(() => { _rcvField.text += $"{player.Nickname}: {message}\n"; _rcvField.verticalScrollbar.value = 1; //* Move to receive field to last message. _rcvField.MoveTextEnd(false); }); }
public static void Disconnect(NeutronPlayer player, string reason) { using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = stream.Writer; writer.WritePacket((byte)Packet.Disconnection); writer.Write(player.Id); writer.Write(reason); player.Write(writer, Helper.GetHandlers().OnPlayerDisconnected); } }
private void CreateUdpPacket(NeutronPlayer player) { byte[] datagram = player.StateObject.SlicedDatagram; //* Get the datagram. byte[] pBuffer = datagram.Decompress(); //* Decompress the packet. NeutronPacket neutronPacket = Helper.PollPacket(pBuffer, player, player, Protocol.Udp); //* Create the packet. _dataForProcessing.Push(neutronPacket); //* Add the packet to the queue. NeutronStatistics.ServerUDP.AddIncoming(datagram.Length); //* Add the incoming bytes to the statistics. }
/// <summary> ///* Envia uma mensagem para o jogador.<br/> ///* (Server-Side). /// </summary> /// <param name="player"></param> /// <param name="packet"></param> /// <param name="message"></param> public static void Error(this NeutronPlayer player, Packet packet, string message, int errorCode = 0) { using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = stream.Writer; writer.WritePacket((byte)Packet.Error); writer.WritePacket((byte)packet); writer.Write(message); writer.Write(errorCode); player.Write(writer); } }
public static void Leave(NeutronPlayer player, MatchmakingMode matchmakingMode) { if (matchmakingMode == MatchmakingMode.Channel) { player.Channel = null; } if (matchmakingMode == MatchmakingMode.Room) { player.Room = null; } player.Matchmaking = Matchmaking(player); }
protected override async void OnPlayerConnected(NeutronPlayer player, bool isMine, Neutron neutron) { if (isMine) { await neutron.Synchronize(); } var players = neutron.GetPlayers(); foreach (var pl in players) { LogHelper.Error(pl.Nickname); } }
//* Client->Server //* Server->Client protected void Send(NeutronStream stream, NeutronPlayer player, bool isServerSide, Protocol protocol) { NeutronStream.IWriter writer = stream.Writer; if (!isServerSide) { Send(stream, protocol); } else { var packet = Helper.PollPacket(writer.ToArray(), player, player, protocol); Neutron.Server.AddPacket(packet); } }
protected void SetNicknameHandler(NeutronPlayer player, string nickname) { if (OnPlayerNicknameChanged.Invoke(player, nickname)) { player.Nickname = nickname; using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = stream.Writer; writer.WritePacket((byte)Packet.Nickname); writer.Write(nickname); player.Write(writer, Helper.GetHandlers().OnPlayerNicknameChanged); } } }
#pragma warning disable IDE1006 protected void iRPCHandler(NeutronPlayer owner, NeutronPlayer sender, short viewId, byte rpcId, byte instanceId, byte[] buffer, RegisterMode registerType, TargetTo targetTo, CacheMode cache, Protocol protocol) #pragma warning restore IDE1006 { void Run((int, int, RegisterMode) key) { bool Send() { MatchmakingTo matchmakingTo = MatchmakingTo.Auto; if (targetTo == TargetTo.Me) { matchmakingTo = MatchmakingTo.Me; } using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = stream.Writer; writer.WritePacket((byte)Packet.iRPC); writer.WritePacket((byte)registerType); writer.Write(viewId); writer.Write(rpcId); writer.Write(instanceId); writer.WriteNext(buffer); MatchmakingHelper.Internal.AddCache(rpcId, viewId, writer, owner, cache, CachedPacket.iRPC); owner.Write(sender, writer, targetTo, matchmakingTo, protocol); } return(true); } if (MatchmakingHelper.Server.GetNetworkObject(key, owner, out NeutronView neutronView)) { if (neutronView.iRPCs.TryGetValue((rpcId, instanceId), out RPCInvoker remoteProceduralCall)) { try { iRPCAttribute iRPCAttribute = remoteProceduralCall.iRPC; if (ReflectionHelper.iRPC(buffer, remoteProceduralCall, owner)) { Send(); } } catch (Exception ex) { LogHelper.Stacktrace(ex); } } else { Send(); } }
protected override void OnPlayerJoinedChannel(NeutronChannel channel, NeutronPlayer player, bool isMine, Neutron neutron) { base.OnPlayerJoinedChannel(channel, player, isMine, neutron); { if (isMine) { using (NeutronStream stream = new NeutronStream()) { var writer = neutron.BeginPlayer(stream, Vector3.zero, Quaternion.identity); writer.Write(); neutron.EndPlayer(stream, 10); } } } }
public void SyncSnapshot(NeutronStream.IReader reader, NeutronPlayer player) { var position = _syncPosition ? reader.ReadVector3() : Vector3.zero; var rotation = _syncRotation ? _compressQuaternion ? reader.ReadCompressedQuaternion(_floatMultiplicationPrecision) : reader.ReadQuaternion() : Quaternion.identity; var scale = _syncScale ? reader.ReadVector3() : Vector3.zero; var timestamp = reader.ReadDouble(); if (_syncPosition) { OnTeleport(position); } NetworkTransformSnapshot snapshot = new NetworkTransformSnapshot( timestamp, LocalTime, position, rotation, scale ); lock (_bufferLock) SnapshotInterpolation.InsertIfNewEnough(snapshot, _buffer); }
public void SyncRigidbody(NeutronStream.IReader reader, NeutronPlayer player) { if (DoNotPerformTheOperationOnTheServer) { if (!_sync) { _sync = true; } var position = reader.ReadVector3(); var velocity = reader.ReadVector3(); var angularVelocity = reader.ReadVector3(); var localTime = reader.ReadDouble(); if (localTime > _lastTime) { _position = position; _velocity = velocity; _angularVelocity = angularVelocity; } _lastTime = localTime; } }
protected void SynchronizeHandler(NeutronPlayer player, Protocol protocol) { //* Envia todos os jogadores conectados para mim. using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = stream.Writer; NeutronPlayer[] players = MatchmakingHelper.Internal.GetPlayersByMatchmakingTo(player, MatchmakingTo.Auto); players = players.Where(x => x.Id != player.Id).ToArray(); writer.WritePacket((byte)Packet.Synchronize); writer.Write((byte)1); writer.WriteNext(players.Serialize().Compress(CompressionMode.Deflate)); player.Write(writer, TargetTo.Me, MatchmakingTo.Me, protocol); } //* Envia-me para todos os jogadores conectados. using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = stream.Writer; writer.WritePacket((byte)Packet.Synchronize); writer.Write((byte)2); writer.WriteNext(player.Serialize().Compress(CompressionMode.Deflate)); player.Write(writer, TargetTo.Others, MatchmakingTo.Auto, protocol); } }
public static NeutronPlayer[] GetPlayersByMatchmakingTo(NeutronPlayer player, MatchmakingTo matchmakingTo) { switch (matchmakingTo) { case MatchmakingTo.Me: return(null); case MatchmakingTo.Server: { return(Neutron.Server.PlayersBySocket.Values.ToArray()); } case MatchmakingTo.Channel: { if (player.IsInChannel()) { return(player.Channel.Players()); } else { LogHelper.Error("Failed to direct packet, channel not found. Join a channel before sending the packet."); } return(default); }
protected override void OnPlayerJoinedChannel(NeutronChannel channel, NeutronPlayer player, bool isMine, Neutron neutron) { base.OnPlayerJoinedChannel(channel, player, isMine, neutron); }
//* Executa o iRPC na instância específicada. #pragma warning disable IDE1006 protected void iRPCHandler(byte rpcId, short viewId, byte instanceId, byte[] parameters, NeutronPlayer player, RegisterMode registerMode) #pragma warning restore IDE1006 { void Run((int, int, RegisterMode) key) //* a key do objeto, o primeiro parâmetro é o ID do jogador ou do Objeto de Rede ou 0(se for objeto de cena), e o segundo é o ID do objeto, e o terceiro é o tipo de objeto. { if (MatchmakingHelper.Server.GetNetworkObject(key, This.LocalPlayer, out NeutronView neutronView)) //* Obtém a instância que enviou o RPC para a rede. { if (neutronView.iRPCs.TryGetValue((rpcId, instanceId), out RPCInvoker remoteProceduralCall)) //* Obtém o RPC com o ID enviado para a rede. { try { //* Executa o RPC, observe que isto não usa reflexão, reflexão é lento irmão, eu uso delegados, e a reflexão para criar os delegados em runtime no Awake do objeto, bem rápido, e funciona no IL2CPP. ReflectionHelper.iRPC(parameters, remoteProceduralCall, player); } catch (Exception ex) { LogHelper.Stacktrace(ex); } } else { LogHelper.Warn("Ignore this: iRpc with this Id not found."); } }
public static void AddCache(int id, int viewId, NeutronStream.IWriter writer, NeutronPlayer player, CacheMode cache, CachedPacket cachedPacket) { //LogHelper.Error(ThreadHelper.GetThreadID()); if (cache != CacheMode.None) { INeutronMatchmaking neutronMatchmaking = player.Matchmaking; if (neutronMatchmaking != null) { NeutronCache dataCache = new NeutronCache(id, writer.ToArray(), player, cachedPacket, cache); neutronMatchmaking.Add(dataCache, viewId); } else { LogHelper.Error("Cache: Matchmaking not found!"); } } }
public static bool AddPlayer(NeutronPlayer player) { return(Neutron.Server.PlayersById.TryAdd(player.Id, player)); }
public static bool IsMine(NeutronPlayer player, int playerId) { return(player.Id == playerId); }
private bool OnCreatePlayer(NeutronStream.IReader reader, bool isServer, bool isMine, NeutronPlayer player, Neutron instance) { if (instance.EndPlayer(reader, out var pos, out var rot)) { NeutronSchedule.ScheduleTask(() => { Neutron.NetworkSpawn(isServer, false, player, _player, pos, rot, instance); }); }