protected override void HandlePacket(Packet packet) { BitBuffer bitBuffer = new BitBuffer(); bitBuffer.PutBytes(packet.getData()); bitBuffer.Flip(); PlayerInput input = PlayerInput.fromBytes(bitBuffer); switch (input.GetInputType()) { case InputType.MOVEMENT: _players[input.GetId()].SetTargetPosition(((MovementInput)input).GetPosition()); break; case InputType.ABILITY: AbilityInput ability = (AbilityInput)input; Vector3 abilityStartPosition = Vector3.zero; switch (ability.GetAbilityType()) { case AbilityType.AUTOATTACK: abilityStartPosition = _players[ability.GetId()].transform.position; AutoAttack autoAttack = SpawnAutoAttack(ability.GetId(), abilityStartPosition, ability.GetTargetPosition()); _lastAbilityId = (_lastAbilityId + 1) % 255; _autoAttacks.Add(_lastAbilityId, autoAttack); break; case AbilityType.FREEZE: _players[ability.GetId()].SpawnFreeze(ability.GetTargetPosition()); break; case AbilityType.FLASH: _players[ability.GetId()].MoveTo(ability.GetTargetPosition()); _players[ability.GetId()].CancelMovement(); break; case AbilityType.EXPLOSION: CreateExplosion(ability.GetTargetPosition()); break; } _channel.SendAll(new AbilityResponse(ability, abilityStartPosition), true); break; case InputType.START_GAME: _lastPlayerId++; Vector3 startPosition = new Vector3(2f, 1.2f, 0f); Player player = CreateServerPlayer(new PlayerInfo(_lastPlayerId, startPosition)); _players.Add(_lastPlayerId, player); _channel.Send(new PlayerInfoBroadcast(_lastPlayerId, _players), packet.getAddress(), true); PlayerInfo playerInfo = new PlayerInfo(_lastPlayerId, player.GetHealth(), new PositionInfo(startPosition)); _channel.SendAllExcluding(new NewPlayerEvent(playerInfo), packet.getAddress(), true); break; } packet = _channel.GetPacket(); bitBuffer.Clear(); }
private void Update() { while (_eventsToHandle.TryDequeue(out var @event)) { switch (@event.Type) { case EventType.Connect: OnConnected(@event.Peer); break; case EventType.Disconnect: OnDisconnected(@event.Peer); break; case EventType.Receive: unsafe { var packet = @event.Packet; var span = new ReadOnlySpan <byte>(packet.Data.ToPointer(), packet.Length); _buffer.FromSpan(ref span, packet.Length); var valid = _detector.ReadHeaderOfPeerId((ushort)@event.Peer.ID, _buffer); if (valid) { var val = _buffer.ReadUInt(); _tick = (ushort)val; } _receivedUnreliable++; _buffer.Clear(); packet.Dispose(); break; } case EventType.Timeout: OnDisconnected(@event.Peer); break; } } _detector.ExecuteLostPackets(); }
private static void StateUpdateTimerOnElapsed(Object source, ElapsedEventArgs e) { _bitBuffer.Clear(); _bitBuffer.AddByte(3); _bitBuffer.AddUShort((ushort)_dataToSend.Count); foreach (PlayerData playerData in _dataToSend) { _bitBuffer.AddUInt(playerData.qX); _bitBuffer.AddUInt(playerData.qY); } }
public void ClearBuffers() { RemovedEntities.Clear(); RemovedComponents.Clear(); ChangedComponents.Clear(); CreatedEntities.Clear(); ChangedComponentsCount = 0; CreatedEntitiesCount = 0; RemovedComponentsCount = 0; RemovedEntitiesCount = 0; }
private static void StateUpdateTimerOnElapsed(Object source, ElapsedEventArgs e) { _bitBuffer.Clear(); _bitBuffer.AddByte(3); _bitBuffer.AddUShort((ushort)_dataToSend.Count); foreach (PlayerData playerData in _dataToSend) { _bitBuffer.AddUShort(playerData.id); _bitBuffer.AddUInt(playerData.qX); _bitBuffer.AddUInt(playerData.qY); } _bitBuffer.ToArray(_buffer); _webServer.SendAll(_connectedIds, new ArraySegment <byte>(_buffer, 0, 3 + 10 * _dataToSend.Count)); }
/// <summary> /// Clients the disconnect handler. /// </summary> /// <param name="sender">Sender.</param> /// <param name="args">Arguments.</param> private void ClientDisconnectHandler(object sender, DisconnectedEventArgs args) { Connection connection = (Connection)sender; Console.WriteLine("Connection from " + connection.EndPoint + " lost"); String UIDBuffer = String.Empty; //Cerca e restituisci il tutto foreach (var conn in clients) { if (conn.Value == connection) //SENDTOSERVER { UIDBuffer = conn.Key; Console.WriteLine("UID TO DESTROY: " + UIDBuffer); } } //https://stackoverflow.com/posts/1608949/revisions //Debug //Delete client disconnected clients.RemoveAll(item => item.Value.Equals(connection)); BitBuffer data = new BitBuffer(1024); data.AddByte((byte)CommandType.DISCONNECTEDCLIENT) .AddString(UIDBuffer); Console.WriteLine("BitBuffer: " + data.Length.ToString()); byte[] BufferNetStack = new byte[data.Length]; data.ToArray(BufferNetStack); data.Clear(); //Add type! //https://stackoverflow.com/questions/5591329/c-sharp-how-to-add-byte-to-byte-array byte[] newArray = new byte[BufferNetStack.Length + 1]; BufferNetStack.CopyTo(newArray, 1); newArray[0] = (byte)SendType.SENDTOSERVER; foreach (var conn in clients) { conn.Value.SendBytes(newArray, SendOption.Reliable); Console.WriteLine("Send to: " + conn.Value.EndPoint.ToString()); } args.Recycle(); }
static void WebServerOnConnect(int id) { _connectedIds.Add(id); _playerDatas[id] = new PlayerData() { id = (ushort)id }; // Tell new client their id _bitBuffer.Clear(); _bitBuffer.AddByte(2); _bitBuffer.AddUShort((ushort)id); _bitBuffer.ToArray(_buffer); _webServer.SendOne(id, new ArraySegment <byte>(_buffer, 0, 3)); }
protected override void Execute(List <GameEntity> entities) { Logger.I.Log(this, "Creating world snapshot."); var e = _game.CreateEntity(); e.AddWorldState(0, _buffer); e.isDestroyed = true; _buffer.Clear(); _syncGroup.GetEntities(_syncBuffer); foreach (var entity in _syncBuffer) { if (!entity.isDestroyed) { e.worldState.EntityCount++; PackEntityUtility.Pack(entity, _buffer); } } }
private void WsOnonData(ArraySegment <byte> obj) { _bitBuffer.Clear(); _bitBuffer.FromArray(obj.Array, obj.Count); ushort messageId = _bitBuffer.ReadUShort(); switch (messageId) { case 0: { ushort id = _bitBuffer.ReadUShort(); if (_ghostCars.ContainsKey(id)) { Destroy(_ghostCars[id].gameObject); _ghostCars.Remove(id); } break; } case 1: { ushort count = _bitBuffer.ReadUShort(); for (int i = 0; i < count; i++) { ushort id = _bitBuffer.ReadUShort(); QuantizedVector3 qPosition = new QuantizedVector3(_bitBuffer.ReadUInt(), _bitBuffer.ReadUInt(), _bitBuffer.ReadUInt()); QuantizedQuaternion qRotation = new QuantizedQuaternion(_bitBuffer.ReadUInt(), _bitBuffer.ReadUInt(), _bitBuffer.ReadUInt(), _bitBuffer.ReadUInt()); ushort qBestTime = _bitBuffer.ReadUShort(); // Ignore it if it is the transform for my own car if (_myId == id || id == 0) { continue; } Vector3 postion = BoundedRange.Dequantize(qPosition, Constants.WORLD_BOUNDS); Quaternion rotation = SmallestThree.Dequantize(qRotation); if (!_ghostCars.ContainsKey(id)) { GameObject newCar = Instantiate(GhostCarPrefab, postion, rotation); _ghostCars[id] = newCar.GetComponent <GhostCarBehavior>(); } else { _ghostCars[id].UpdateTransform(postion, rotation); float bestTime = HalfPrecision.Dequantize(qBestTime); _ghostCars[id].UpdatebestTime(bestTime); } } break; } case 2: { ushort id = _bitBuffer.ReadUShort(); _myId = id; break; } } }
/// <summary> /// Consumers the thread. /// </summary> /// <param name="arg">Argument.</param> private static void ConsumerThread(object arg) { ClientMessageReceived item; //while (true) Console.WriteLine("Queue: " + Server.QueueMessages.Count.ToString()); while (!Server.QueueMessages.IsEmpty) { bool isSuccessful = Server.QueueMessages.TryDequeue(out item); Console.WriteLine("Dequeue: " + isSuccessful); if (isSuccessful) { //https://stackoverflow.com/questions/943398/get-int-value-from-enum-in-c-sharp //https://msdn.microsoft.com/it-it/library/system.enum.getvalues(v=vs.110).aspx //http://csharp.net-informations.com/statements/enum.htm if (((byte)SendType.SENDTOALL).ToString() == item.MessageBytes.GetValue(0).ToString()) //0 { //BROADCAST (SENDTOALL) Console.WriteLine("BROADCAST (SENDTOALL)"); //Send data received to all client in List foreach (var conn in Server.clients) { if (true) { conn.Value.SendBytes(item.MessageBytes, item.SOClientConnected); Console.WriteLine("Send to: " + conn.Value.EndPoint.ToString()); } } } else if ((byte)SendType.SENDTOOTHER == (byte)item.MessageBytes.GetValue(0)) //1 { //BROADCAST (SENDTOOTHER) Console.WriteLine("BROADCAST (SENDTOOTHER)"); //Call Objects Table var col = db.GetCollection <Objects>("objects"); //Parser Message //Remove first byte (type) //https://stackoverflow.com/questions/31550484/faster-code-to-remove-first-elements-from-byte-array byte STypeBuffer = item.MessageBytes[0]; byte[] NewBufferReceiver = new byte[item.MessageBytes.Length - 1]; Array.Copy(item.MessageBytes, 1, NewBufferReceiver, 0, NewBufferReceiver.Length); //Deserialize message using NetStack //Reset bit buffer for further reusing BitBuffer data = new BitBuffer(1024); data.FromArray(NewBufferReceiver, NewBufferReceiver.Length); byte TypeBuffer = data.ReadByte(); string OwnerPlayer = data.ReadString(); bool isKine = data.ReadBool(); uint IDObject = data.ReadUInt(); CompressedVector3 position = new CompressedVector3(data.ReadUInt(), data.ReadUInt(), data.ReadUInt()); CompressedQuaternion rotation = new CompressedQuaternion(data.ReadByte(), data.ReadShort(), data.ReadShort(), data.ReadShort()); // Read Vector3 Compress Velocity //ushort compressedVelocityX = HalfPrecision.Compress(speed); Vector3 VelocityReceived = new Vector3(HalfPrecision.Decompress(data.ReadUShort()), HalfPrecision.Decompress(data.ReadUShort()), HalfPrecision.Decompress(data.ReadUShort())); //Read Float InterpolationTime float InterpolationTime = HalfPrecision.Decompress(data.ReadUShort()); // Check if bit buffer is fully unloaded Console.WriteLine("Bit buffer is empty: " + data.IsFinished); //Decompress Vector and Quaternion //Create a new BoundedRange array for Vector3 position, each entry has bounds and precision BoundedRange[] worldBounds = new BoundedRange[3]; worldBounds[0] = new BoundedRange(-50f, 50f, 0.05f); // X axis worldBounds[1] = new BoundedRange(0f, 25f, 0.05f); // Y axis worldBounds[2] = new BoundedRange(-50f, 50f, 0.05f); // Z axis //Decompress position data Vector3 decompressedPosition = BoundedRange.Decompress(position, worldBounds); // Decompress rotation data Quaternion decompressedRotation = SmallestThree.Decompress(rotation); if (Server.DEBUG) { Console.WriteLine("RECEIVED DATA: "); Console.WriteLine("TYPE RECEIVED: " + TypeBuffer.ToString()); Console.WriteLine("IDObject RECEIVED: " + IDObject.ToString()); Console.WriteLine("UID RECEIVED: " + OwnerPlayer); Console.WriteLine("isKinematic RECEIVED: " + isKine.ToString()); Console.WriteLine("POS RECEIVED: " + decompressedPosition.X.ToString() + ", " + decompressedPosition.Y.ToString() + ", " + decompressedPosition.Z.ToString()); Console.WriteLine("ROT RECEIVED: " + decompressedRotation.X.ToString() + ", " + decompressedRotation.Y.ToString() + ", " + decompressedRotation.Z.ToString() + ", " + decompressedRotation.W.ToString()); Console.WriteLine("PosX: " + decompressedPosition.X); Console.WriteLine("PosY: " + decompressedPosition.Y); Console.WriteLine("PosZ: " + decompressedPosition.Z); Console.WriteLine("VEL RECEIVED: " + VelocityReceived.X.ToString() + ", " + VelocityReceived.Y.ToString() + ", " + VelocityReceived.Z.ToString()); Console.WriteLine("INTERPOLATION TIME: " + InterpolationTime.ToString()); //var ReceiveMessageFromGameObjectBuffer = new ReceiveMessageFromGameObject(); //NOT USED! } //Check if ObjectReceived.ID <> 0 if (IDObject != 0) { var MVobject = new Objects { IDObject = (int)IDObject, isKine = isKine, PosX = decompressedPosition.X, PosY = decompressedPosition.Y, PosZ = decompressedPosition.Z, RotX = decompressedRotation.X, RotY = decompressedRotation.Y, RotZ = decompressedRotation.Z, RotW = decompressedRotation.W, UID = IDObject.ToString() + ";" + OwnerPlayer }; //Debug Console.WriteLine("MVobject PosX: " + MVobject.PosX); Console.WriteLine("MVobject PosY: " + MVobject.PosY); Console.WriteLine("MVobject PosZ: " + MVobject.PosZ); if ((byte)PacketId.OBJECT_SPAWN == TypeBuffer) { // Insert new customer document (Id will be auto-incremented) col.Insert(MVobject); // Create unique index in Name field col.EnsureIndex(x => x.UID, true); Console.WriteLine("OBJECT SPAWN SAVED"); } else if ((byte)PacketId.OBJECT_MOVE == TypeBuffer) { //Check if record exist if (col.Count(Query.EQ("UID", IDObject.ToString() + ";" + OwnerPlayer)) == 1) { //Search and update // Now, search for document your document var ObjectsFinded = col.FindOne(x => x.UID == IDObject.ToString() + ";" + OwnerPlayer); //Update data ObjectsFinded.isKine = isKine; ObjectsFinded.PosX = decompressedPosition.X; ObjectsFinded.PosY = decompressedPosition.Y; ObjectsFinded.PosZ = decompressedPosition.Z; ObjectsFinded.RotX = decompressedRotation.X; ObjectsFinded.RotY = decompressedRotation.Y; ObjectsFinded.RotZ = decompressedRotation.Z; ObjectsFinded.RotW = decompressedRotation.W; //Save data to Objects DB if (col.Update(ObjectsFinded)) { Console.WriteLine("UPDATE OBJECT IN DB"); } else { Console.WriteLine("*NOT* UPDATED OBJECT IN DB"); } } else { col.Insert(MVobject); //Insert data to Objects DB col.EnsureIndex(x => x.UID, true); //Create unique index in Name field Console.WriteLine("INSERT OBJECT IN DB"); } Console.WriteLine("OBJECT MOVE"); } else if ((byte)PacketId.OBJECT_UNSPAWN == TypeBuffer) { if (col.Count(Query.EQ("UID", IDObject.ToString() + ";" + OwnerPlayer)) == 1) { col.Delete(Query.EQ("UID", IDObject.ToString() + ";" + OwnerPlayer)); //Save data to Objects DB Console.WriteLine("DELETE OBJECT FROM DB"); } else { Console.WriteLine("OBJECT UNSPAWN NOT IN DB");; } Console.WriteLine("OBJECT UNSPAWN"); } } // END Check ObjectReceived.ID <> 0 //Send data received to all other client in List Console.WriteLine("SEND MESSAGE TO OTHER CLIENTS"); foreach (var conn in Server.clients) { if (conn.Value != item.ClientConnected) //SENDTOOTHER { conn.Value.SendBytes(item.MessageBytes, item.SOClientConnected); Console.WriteLine("Send to: " + conn.Value.EndPoint.ToString()); } } } else if ((byte)SendType.SENDTOSERVER == (byte)item.MessageBytes.GetValue(0)) //2 { //FOR NOW ECHO SERVER (SENDTOSERVER) Console.WriteLine("CLIENT TO SERVER (SENDTOSERVER)"); //Parser Message //Remove first byte (type) //https://stackoverflow.com/questions/31550484/faster-code-to-remove-first-elements-from-byte-array byte STypeBuffer = item.MessageBytes[0]; byte[] NewBufferReceiver = new byte[item.MessageBytes.Length - 1]; Array.Copy(item.MessageBytes, 1, NewBufferReceiver, 0, NewBufferReceiver.Length); //Deserialize message using NetStack //Reset bit buffer for further reusing BitBuffer data = new BitBuffer(1024); data.FromArray(NewBufferReceiver, NewBufferReceiver.Length); byte CommandTypeBuffer = data.ReadByte(); string Answer = data.ReadString(); // Check if bit buffer is fully unloaded Console.WriteLine("Bit buffer is empty: " + data.IsFinished); String UIDBuffer = String.Empty; if (STypeBuffer == 2) { if ((sbyte)CommandType.LOGIN == CommandTypeBuffer) { //Cerca e restituisci il tutto foreach (var conn in Server.clients) { if (conn.Value == item.ClientConnected) //SENDTOSERVER { //DONE: Check here if user exist and password correct //Get users collection var col = db.GetCollection <Users>("users"); Console.WriteLine("COMMAND RECEIVED: " + Answer); //Parse HMessageReceived string[] words = Answer.Split(';'); //words[0] = Login; words[1] = Password if (col.Count(Query.EQ("UserName", words[0])) == 1) { var results = col.Find(Query.EQ("UserName", words[0])); string UserPasswordRecord = string.Empty; foreach (var c in results) { Console.WriteLine("#{0} - {1}", c.Id, c.UserName); UserPasswordRecord = c.UserPassword; } //Verify password ScryptEncoder encoder = new ScryptEncoder(); //Check password if (encoder.Compare(words[1], UserPasswordRecord)) { //OK UIDBuffer = conn.Key; Console.WriteLine("UID: " + UIDBuffer); } else { //*NOT* OK UIDBuffer = string.Empty; Console.WriteLine("UID: ERROR PASSWORD" + UIDBuffer); } } else { UIDBuffer = string.Empty; Console.WriteLine("UID: USER NOT EXISTS!" + UIDBuffer); } } } } } //Reset bit buffer for further reusing data.Clear(); data.AddByte((byte)CommandType.LOGIN) .AddString(UIDBuffer); byte[] BufferNetStack = new byte[data.Length]; data.ToArray(BufferNetStack); data.Clear(); //SEND MESSAGE // Add type! //https://stackoverflow.com/questions/5591329/c-sharp-how-to-add-byte-to-byte-array byte[] newArray = new byte[BufferNetStack.Length + 1]; BufferNetStack.CopyTo(newArray, 1); newArray[0] = (byte)SendType.SENDTOSERVER; item.ClientConnected.SendBytes(newArray, item.SOClientConnected); if (DEBUG) { Console.WriteLine("Data Lenghts: " + newArray.Length.ToString()); Console.WriteLine("Data Lenghts NetStack: " + BufferNetStack.Length.ToString()); Console.WriteLine("Data Lenghts BitBuffer: " + data.Length.ToString()); Console.WriteLine("Message sent!"); } Console.WriteLine("Send to: " + item.ClientConnected.EndPoint.ToString()); //HERE SEND TO ALL CLIENTS OBJECTS DB //DONE: Add code to send all clients Console.WriteLine("SEND ALL OBJECTS TO CLIENT"); //Call Objects Table var col_objects = db.GetCollection <Objects>("objects"); //Recovers all objects in the table var results_objects = col_objects.Find(Query.GT("_id", 0)); //Foreach send them to the client connected foreach (var o in results_objects) { Console.WriteLine("SEND IDOBJECT: " + o.IDObject.ToString()); //SEND USING NETSTACK SERIALIZATION // Create a new BoundedRange array for Vector3 position, each entry has bounds and precision BoundedRange[] worldBounds = new BoundedRange[3]; worldBounds[0] = new BoundedRange(-50f, 50f, 0.05f); // X axis worldBounds[1] = new BoundedRange(0f, 25f, 0.05f); // Y axis worldBounds[2] = new BoundedRange(-50f, 50f, 0.05f); // Z axis //Convert from HazelUDPTestClient.Vector3 at System.Numerics.Vector3 System.Numerics.Vector3 InternalPos = new System.Numerics.Vector3(o.PosX, o.PosY, o.PosZ); //Compress position data CompressedVector3 compressedPosition = BoundedRange.Compress(InternalPos, worldBounds); // Read compressed data Console.WriteLine("Compressed position - X: " + compressedPosition.x + ", Y:" + compressedPosition.y + ", Z:" + compressedPosition.z); //Convert from HazelUDPTestClient.Quaternion at System.Numerics.Quaternion System.Numerics.Quaternion InternalRot = new System.Numerics.Quaternion(o.RotX, o.RotY, o.RotZ, o.RotW); // Compress rotation data CompressedQuaternion compressedRotation = SmallestThree.Compress(InternalRot); // Read compressed data Console.WriteLine("Compressed rotation - M: " + compressedRotation.m + ", A:" + compressedRotation.a + ", B:" + compressedRotation.b + ", C:" + compressedRotation.c); //Add Velocity Vector (0,0,0) Vector3 velocity = Vector3.Zero; //Add and compress Interporlation Time ushort compressedTimeInterpolation = HalfPrecision.Compress(0f); //Reset bit buffer for further reusing data.Clear(); //Serialization data.AddByte((byte)PacketId.OBJECT_MOVE) .AddString(o.UID.Split(';')[1]) //OwnerPlayer .AddBool(o.isKine) .AddUInt((uint)o.IDObject) .AddUInt(compressedPosition.x) .AddUInt(compressedPosition.y) .AddUInt(compressedPosition.z) .AddByte(compressedRotation.m) .AddShort(compressedRotation.a) .AddShort(compressedRotation.b) .AddShort(compressedRotation.c) //Add dummy date (0,0,0) .AddUShort(HalfPrecision.Compress(velocity.X)) .AddUShort(HalfPrecision.Compress(velocity.Y)) .AddUShort(HalfPrecision.Compress(velocity.Z)) .AddUShort(compressedTimeInterpolation); Console.WriteLine("BitBuffer: " + data.Length.ToString()); byte[] BufferNetStackObject = new byte[data.Length]; data.ToArray(BufferNetStackObject); data.Clear(); //https://discordapp.com/channels/515987760281288707/515987760281288711/527744788745814028 //MA soprattutto: https://discordapp.com/channels/515987760281288707/515987760281288711/536428267851350017 //Okay guys, after some debugging I've found the mistake in the original BitBuffer implementation, //Alex forgot to check index boundaries during conversion so this is why + 4 bytes was required for shifting. //Now it's fixed and no longer needed I hope //https://github.com/nxrighthere/NetStack/commit/f381a88751fa0cb72af2cad7652a973d570d3dda //SEND MESSAGE // Add type! //https://stackoverflow.com/questions/5591329/c-sharp-how-to-add-byte-to-byte-array byte[] newArrayObject = new byte[BufferNetStackObject.Length + 1]; //Create +1 NewArrayObject BufferNetStackObject.CopyTo(newArrayObject, 1); //Coping start from position 1 (NOT 0) newArrayObject[0] = (byte)SendType.SENDTOOTHER; //Coping position 0 byte SendType item.ClientConnected.SendBytes(newArrayObject, item.SOClientConnected); //Send new packet if (DEBUG) { Console.WriteLine("Data Lenghts: " + newArray.Length.ToString()); Console.WriteLine("Data Lenghts NetStack: " + BufferNetStack.Length.ToString()); Console.WriteLine("Message sent!"); } } } } } }
static void Main(string[] args) { _rand = new Random(Environment.TickCount); SslConfig sslConfig; TcpConfig tcpConfig = new TcpConfig(true, 5000, 20000); Console.WriteLine("Setting up secure server"); sslConfig = new SslConfig(true, "cert.pfx", "", SslProtocols.Tls12); _webServer = new SimpleWebServer(10000, tcpConfig, 16 * 1024, 3000, sslConfig); _webServer.Start(Constants.GAME_PORT); Console.WriteLine("Server started"); _webServer.onConnect += WebServerOnConnect; _webServer.onData += WebServerOnData; _webServer.onDisconnect += WebServerOnDisconnect; Timer stateUpdateTimer = new Timer(1f / Constants.SERVER_TICKRATE * 1000); stateUpdateTimer.Elapsed += StateUpdateTimerOnElapsed; stateUpdateTimer.AutoReset = true; stateUpdateTimer.Enabled = true; while (!Console.KeyAvailable) { _webServer.ProcessMessageQueue(); // GUARD, DONT DO STATE STUFF IF WE ARE WAITING if (_waitingOnStateTimer) { continue; } switch (_currentState) { case GameState.Waiting: { if (_connectedIds.Count >= 2) { _currentState = GameState.Begin; SendStateUpdate(_currentState); } break; } case GameState.Begin: { // Set timer to go to builder state beginTimer = new Timer(SECONDS_WAITING_IN_BEGIN * 1000); beginTimer.AutoReset = false; beginTimer.Start(); _waitingOnStateTimer = true; beginTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; _movedObjects = new HashSet <ushort>(); _currentState = GameState.Builder; SendStateUpdate(_currentState); }; break; } case GameState.Builder: { // Set timer to go to builder state buildTimer = new Timer(SECONDS_WAITING_IN_BUILD * 1000); buildTimer.AutoReset = false; buildTimer.Start(); _waitingOnStateTimer = true; buildTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; // Reset everyones guesses foreach (PlayerData playerData in _playerDatas.Values) { playerData.guesses.Clear(); } _currentState = GameState.Search; SendStateUpdate(_currentState); }; break; } case GameState.Search: { // Set timer to go to scoring state searchTimer = new Timer(SECONDS_WAITING_IN_SEARCH * 1000); searchTimer.AutoReset = false; searchTimer.Start(); _waitingOnStateTimer = true; searchTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; _currentState = GameState.Scoring; SendStateUpdate(_currentState); }; break; } case GameState.Scoring: { short builderPoints = 0; _bitBuffer.Clear(); _bitBuffer.AddByte(7); _bitBuffer.AddUShort((ushort)_playerDatas.Count); _bitBuffer.ToArray(_buffer); _webServer.SendAll(_connectedIds, new ArraySegment <byte>(_buffer, 0, 3 + 2 * _playerDatas.Count)); if (_connectedIds.Count >= 2) { _currentState = GameState.Begin; } else { _currentState = GameState.Waiting; } SendStateUpdate(_currentState); break; } } } Console.WriteLine("Closing server"); _webServer.Stop(); }
public void Reset() { buffer.Clear(); }
static void Main(string[] args) { _rand = new Random(Environment.TickCount); SslConfig sslConfig; TcpConfig tcpConfig = new TcpConfig(true, 5000, 20000); Console.WriteLine("Setting up secure server"); sslConfig = new SslConfig(true, "cert.pfx", "", SslProtocols.Tls12); _webServer = new SimpleWebServer(10000, tcpConfig, 16 * 1024, 3000, sslConfig); _webServer.Start(Constants.GAME_PORT); Console.WriteLine("Server started"); _webServer.onConnect += WebServerOnConnect; _webServer.onData += WebServerOnData; _webServer.onDisconnect += WebServerOnDisconnect; Timer stateUpdateTimer = new Timer(1f / Constants.SERVER_TICKRATE * 1000); stateUpdateTimer.Elapsed += StateUpdateTimerOnElapsed; stateUpdateTimer.AutoReset = true; stateUpdateTimer.Enabled = true; while (!Console.KeyAvailable) { _webServer.ProcessMessageQueue(); // GUARD, DONT DO STATE STUFF IF WE ARE WAITING if (_waitingOnStateTimer) { continue; } switch (_currentState) { case GameState.Waiting: { if (_handshakenClientCount >= 2 && _connectedIds.Count >= 2) { _currentState = GameState.Begin; SendStateUpdate(_currentState); } break; } case GameState.Begin: { // Set timer to go to builder state beginTimer = new Timer(SECONDS_WAITING_IN_BEGIN * 1000); beginTimer.AutoReset = false; beginTimer.Start(); _waitingOnStateTimer = true; beginTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; _movedObjects = new Dictionary <ushort, Tuple <ushort, ushort> >(); _currentState = GameState.Builder; SendStateUpdate(_currentState); }; break; } case GameState.Builder: { // Set timer to go to builder state buildTimer = new Timer(SECONDS_WAITING_IN_BUILD * 1000); buildTimer.AutoReset = false; buildTimer.Start(); _waitingOnStateTimer = true; buildTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; // Reset everyones guesses foreach (PlayerData playerData in _playerDatas.Values) { playerData.guesses.Clear(); } // Make sure builder actually moved something, // if he didnt, goto scoring and give everyone else a point if (_movedObjects.Count > 0) { _currentState = GameState.Search; } else { foreach (PlayerData data in _playerDatas.Values) { if (data.id != _builderId) { data.points += 1; } _playerDatas[_builderId].points -= (ushort)_handshakenClientCount; } _currentState = GameState.Scoring; } SendStateUpdate(_currentState); }; break; } case GameState.Search: { // Set timer to go to scoring state searchTimer = new Timer(SECONDS_WAITING_IN_SEARCH * 1000); searchTimer.AutoReset = false; searchTimer.Start(); _waitingOnStateTimer = true; searchTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; _currentState = GameState.Scoring; SendStateUpdate(_currentState); }; break; } case GameState.Scoring: { // Set timer to wait for points to come in from clients scoringTimer = new Timer(SECONDS_WAITING_IN_SCORING * 1000); scoringTimer.AutoReset = false; scoringTimer.Start(); _waitingOnStateTimer = true; scoringTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; // Tell everyone everyones scores _bitBuffer.Clear(); _bitBuffer.AddByte(7); _bitBuffer.AddUShort((ushort)_playerDatas.Count); foreach (PlayerData data in _playerDatas.Values) { _bitBuffer.AddUShort(data.id); _bitBuffer.AddShort(data.points); } _bitBuffer.ToArray(_buffer); _webServer.SendAll(_connectedIds, new ArraySegment <byte>(_buffer, 0, 3 + 4 * _playerDatas.Count)); if (_handshakenClientCount >= 2 && _connectedIds.Count >= 2) { _currentState = GameState.Begin; } else { _currentState = GameState.Waiting; } SendStateUpdate(_currentState); }; break; } } } Console.WriteLine("Closing server"); _webServer.Stop(); }
private void WebClientOnonData(ArraySegment <byte> data) { _bitBuffer.Clear(); _bitBuffer.FromArray(data.Array, data.Count); byte messageId = _bitBuffer.ReadByte(); switch (messageId) { case 2: { _myId = _bitBuffer.ReadUShort(); // Put my name into _names too _names[_myId] = ConnectUIController.DisplayName; _currentState = (GameState)_bitBuffer.ReadByte(); // Read all the ids and names it gives me and store it into _names to be used when players get spawned ushort count = _bitBuffer.ReadUShort(); _scoreboardController.ResetScores(); for (int i = 0; i < count; i++) { ushort id = _bitBuffer.ReadUShort(); string name = _bitBuffer.ReadString(); short score = _bitBuffer.ReadShort(); _names[id] = name; Debug.Log("id: " + id + ", name: " + name); _scoreboardController.UpdateEntry(id, name, score); } _scoreboardController.DrawBoard(); StatusText.enabled = true; if (_currentState == GameState.Waiting) { StatusText.text = "Waiting for at least two players"; } else { StatusText.text = "Waiting for current round to end..."; _musicController.Pause(); } _handShakeComplete = true; break; } case 3: { // GUARD FROM SETTING PLAYER POSITIONS UNTIL WE HAVE OUR ID if (!_handShakeComplete) { break; } ushort count = _bitBuffer.ReadUShort(); for (int i = 0; i < count; i++) { ushort id = _bitBuffer.ReadUShort(); uint qX = _bitBuffer.ReadUInt(); uint qY = _bitBuffer.ReadUInt(); // GUARD FROM CHANGING LOCAL PLAYERS POSITION if (id == _myId) { continue; } QuantizedVector2 qPosition = new QuantizedVector2(qX, qY); Vector2 position = BoundedRange.Dequantize(qPosition, Constants.WORLD_BOUNDS); if (!_otherPlayers.ContainsKey(id)) { // Create new player GameObject newPlayer = Instantiate(OtherPlayerPrefab, position, Quaternion.identity); Destroy(newPlayer.GetComponent <Rigidbody2D>()); Destroy(newPlayer.GetComponent <CircleCollider2D>()); Destroy(newPlayer.GetComponent <PlayerController>()); Destroy(newPlayer.GetComponent <MusicController>()); PositionInterp positionInterp = newPlayer.GetComponent <PositionInterp>(); positionInterp.enabled = true; _otherPlayers[id] = positionInterp; newPlayer.GetComponent <Nametag>().SetName(_names[id]); _overrideDirtySendRule = true; } // Update the other players position _otherPlayers[id].PushNewPosition(position); } break; } case 4: { ushort id = _bitBuffer.ReadUShort(); if (_otherPlayers.ContainsKey(id)) { Destroy(_otherPlayers[id].gameObject); _otherPlayers.Remove(id); } _scoreboardController.RemoveEntry(id); _scoreboardController.DrawBoard(); break; } case 5: { _currentState = (GameState)_bitBuffer.ReadByte(); HandleStateChange(_currentState); break; } case 7: { ushort count = _bitBuffer.ReadUShort(); _scoreboardController.ResetScores(); for (int i = 0; i < count; i++) { ushort id = _bitBuffer.ReadUShort(); short points = _bitBuffer.ReadShort(); _scoreboardController.UpdateEntry(id, _names[id], points); } _scoreboardController.DrawBoard(); break; } case 9: { ushort id = _bitBuffer.ReadUShort(); string name = _bitBuffer.ReadString(); _names[id] = name; // Add this new guy to the scoreboard _scoreboardController.UpdateEntry(id, name, 0); _scoreboardController.DrawBoard(); break; } case 13: { ushort id = _bitBuffer.ReadUShort(); if (_myId != id) { _otherPlayers[id].GetComponent <PlayerAnimationController>().Explode(); _audioSource.PlayOneShot(ExplodeSound); } break; } } }
private static void StateUpdateTimerOnElapsed(Object source, ElapsedEventArgs e) { _bitBuffer.Clear(); _bitBuffer.AddByte(3); _bitBuffer.AddUShort((ushort)_dataToSend.Count); }
private static void StateUpdateTimerOnElapsed(Object source, ElapsedEventArgs e) { _bitBuffer.Clear(); _bitBuffer.AddByte(3); }
public static bool Equals(GameEntity entityA, GameEntity entityB, BitBuffer bufferA, BitBuffer bufferB) { void Clear() { bufferA.Clear(); bufferB.Clear(); } Clear(); if (entityA.hasPosition && entityB.hasPosition) { entityA.position.Serialize(bufferA); entityB.position.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasPosition && !entityA.hasPosition) { } else { return(false); } Clear(); if (entityA.hasDirection && entityB.hasDirection) { entityA.direction.Serialize(bufferA); entityB.direction.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasDirection && !entityA.hasDirection) { } else { return(false); } Clear(); if (entityA.hasSprite && entityB.hasSprite) { entityA.sprite.Serialize(bufferA); entityB.sprite.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasSprite && !entityA.hasSprite) { } else { return(false); } Clear(); if (entityA.isMover != entityB.isMover) { return(false); } Clear(); if (entityA.hasMove && entityB.hasMove) { entityA.move.Serialize(bufferA); entityB.move.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasMove && !entityA.hasMove) { } else { return(false); } Clear(); if (entityA.hasLastMoveTick && entityB.hasLastMoveTick) { entityA.lastMoveTick.Serialize(bufferA); entityB.lastMoveTick.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasLastMoveTick && !entityA.hasLastMoveTick) { } else { return(false); } Clear(); if (entityA.hasMoverID && entityB.hasMoverID) { entityA.moverID.Serialize(bufferA); entityB.moverID.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasMoverID && !entityA.hasMoverID) { } else { return(false); } Clear(); if (entityA.hasTick && entityB.hasTick) { entityA.tick.Serialize(bufferA); entityB.tick.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasTick && !entityA.hasTick) { } else { return(false); } Clear(); if (entityA.hasIce && entityB.hasIce) { entityA.ice.Serialize(bufferA); entityB.ice.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasIce && !entityA.hasIce) { } else { return(false); } Clear(); if (entityA.isCharacter != entityB.isCharacter) { return(false); } Clear(); if (entityA.hasControlledBy && entityB.hasControlledBy) { entityA.controlledBy.Serialize(bufferA); entityB.controlledBy.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasControlledBy && !entityA.hasControlledBy) { } else { return(false); } Clear(); if (entityA.hasConnection && entityB.hasConnection) { entityA.connection.Serialize(bufferA); entityB.connection.Serialize(bufferB); if (!bufferA.Equals(bufferB)) { return(false); } } else if (!entityA.hasConnection && !entityA.hasConnection) { } else { return(false); } Clear(); if (entityA.isSync != entityB.isSync) { return(false); } return(true); }
public void Execute() { while (_responses.TryDequeue(out var response)) { switch (response) { case NetworkThreadResponse.StartSuccess: Logger.I.Log(this, "Server is working"); State = ServerState.Working; break; case NetworkThreadResponse.StartFailure: Logger.I.Log(this, "Server start failed"); State = ServerState.Stopped; break; case NetworkThreadResponse.Stoppoed: Logger.I.Log(this, "Server is stopped"); ClearBuffers(); while (_eventsToHandle.TryDequeue(out _)) { } State = ServerState.Stopped; break; } } if (State != ServerState.Working) { return; } while (_eventsToHandle.TryDequeue(out var @event)) { unsafe { switch (@event.EventType) { case EventType.Connect: _handler.OnClientConnected(@event.Peer); break; case EventType.Disconnect: _handler.OnClientDisconnected(@event.Peer); break; case EventType.Receive: _currentPeerId = (ushort)@event.Peer.ID; _handler.CurrentClientId = _currentPeerId; var e = _game.GetEntityWithConnection(_currentPeerId); if (e == null) { Marshal.FreeHGlobal(@event.Data); break; } var headerSpan = new ReadOnlySpan <ushort>(@event.Data.ToPointer(), 2); var commandCount = headerSpan[0]; var commandLength = headerSpan[1]; if (commandCount > 0) { var commandsSpan = new ReadOnlySpan <byte>(IntPtr.Add(@event.Data, 4).ToPointer(), commandLength); _fromClients.Clear(); _fromClients.FromSpan(ref commandsSpan, commandLength); ServerCommandExecutor.Execute(_handler, _fromClients, commandCount); } Marshal.FreeHGlobal(@event.Data); _currentPeerId = ushort.MaxValue; break; case EventType.Timeout: _handler.OnClientDisconnected(@event.Peer); break; } } } }
static void Main(string[] args) { _rand = new Random(Environment.TickCount); SslConfig sslConfig; TcpConfig tcpConfig = new TcpConfig(true, 5000, 20000); Console.WriteLine("Setting up secure server"); sslConfig = new SslConfig(true, "cert.pfx", "", SslProtocols.Tls12); _webServer = new SimpleWebServer(10000, tcpConfig, 16 * 1024, 3000, sslConfig); _webServer.Start(Constants.GAME_PORT); Console.WriteLine("Server started"); _webServer.onConnect += WebServerOnConnect; _webServer.onData += WebServerOnData; _webServer.onDisconnect += WebServerOnDisconnect; Timer stateUpdateTimer = new Timer(1f / Constants.SERVER_TICKRATE * 1000); stateUpdateTimer.Elapsed += StateUpdateTimerOnElapsed; stateUpdateTimer.AutoReset = true; stateUpdateTimer.Enabled = true; while (!Console.KeyAvailable) { _webServer.ProcessMessageQueue(); // GUARD, DONT DO STATE STUFF IF WE ARE WAITING if (_waitingOnStateTimer) { continue; } switch (_currentState) { case GameState.Waiting: { if (_connectedIds.Count >= 2) { _currentState = GameState.Begin; SendStateUpdate(_currentState); } break; } case GameState.Begin: { // Set timer to go to builder state beginTimer = new Timer(SECONDS_WAITING_IN_BEGIN * 1000); beginTimer.AutoReset = false; beginTimer.Start(); _waitingOnStateTimer = true; beginTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; _movedObjects = new List <ushort>(); _currentState = GameState.Builder; SendStateUpdate(_currentState); }; break; } case GameState.Builder: { // Set timer to go to builder state buildTimer = new Timer(SECONDS_WAITING_IN_BUILD * 1000); buildTimer.AutoReset = false; buildTimer.Start(); _waitingOnStateTimer = true; buildTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; // Reset everyones guesses foreach (PlayerData playerData in _playerDatas.Values) { playerData.guesses.Clear(); } _currentState = GameState.Search; SendStateUpdate(_currentState); }; break; } case GameState.Search: { // Set timer to go to scoring state searchTimer = new Timer(SECONDS_WAITING_IN_SEARCH * 1000); searchTimer.AutoReset = false; searchTimer.Start(); _waitingOnStateTimer = true; searchTimer.Elapsed += delegate(Object source, ElapsedEventArgs e) { _waitingOnStateTimer = false; _currentState = GameState.Scoring; SendStateUpdate(_currentState); }; break; } case GameState.Scoring: { short builderPoints = 0; _bitBuffer.Clear(); _bitBuffer.AddByte(7); _bitBuffer.AddUShort((ushort)_playerDatas.Count); foreach (var playerData in _playerDatas.Values) { // GUARD, DON'T SCORE THE BUILDER THIS WAY if (playerData.id == _builderId) { continue; } // Free points for objects builder couldnt move // A point for a correct guess, minus point for a wrong guess int numCorrect = _movedObjects.Distinct().Intersect(playerData.guesses).Count(); int newPoints = (numCorrect * 2) - playerData.guesses.Count + (NUMBER_OF_MOVEABLE_OBJECTS - _movedObjects.Count); playerData.points += (short)newPoints; // Builder gets a point for each player who couldnt find any differences if (numCorrect == 0) { builderPoints += 1; } _bitBuffer.AddUShort(playerData.id); _bitBuffer.AddShort(playerData.points); } _playerDatas[_builderId].points += builderPoints; _bitBuffer.AddUShort((ushort)_builderId); _bitBuffer.AddShort(_playerDatas[_builderId].points); _bitBuffer.ToArray(_buffer); _webServer.SendAll(_connectedIds, new ArraySegment <byte>(_buffer, 0, 3 + 2 * _playerDatas.Count)); if (_connectedIds.Count >= 2) { _currentState = GameState.Begin; } else { _currentState = GameState.Waiting; } SendStateUpdate(_currentState); break; } } } Console.WriteLine("Closing server"); _webServer.Stop(); }
private unsafe void ExecuteState(IntPtr state) { PackedDataFlags flags; int cursor; if (_firstPacket) { _firstPacket = false; flags = PackedDataFlags.Commands | PackedDataFlags.CreatedEntities; cursor = 0; } else { flags = (PackedDataFlags)Marshal.ReadByte(state); cursor = 1; } #region commands if ((flags & PackedDataFlags.Commands) == PackedDataFlags.Commands) { var commandsHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var commandCount = commandsHeaderSpan[0]; var commandLength = commandsHeaderSpan[1]; cursor += 4; if (commandCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), commandLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, commandLength); ClientCommandExecutor.Execute(_handler, _fromServer, commandCount); cursor += commandLength; } } #endregion #region created entities if ((flags & PackedDataFlags.CreatedEntities) == PackedDataFlags.CreatedEntities) { var createdEntitiesHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var createdEntitiesCount = createdEntitiesHeaderSpan[0]; var createdEntitiesLength = createdEntitiesHeaderSpan[1]; cursor += 4; if (createdEntitiesCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), createdEntitiesLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, createdEntitiesLength); UnpackEntityUtility.CreateEntities(_game, _fromServer, createdEntitiesCount); cursor += createdEntitiesLength; } } #endregion #region removed entities if ((flags & PackedDataFlags.RemovedEntities) == PackedDataFlags.RemovedEntities) { var removedEntitiesHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var removedEntitiesCount = removedEntitiesHeaderSpan[0]; var removedEntitiesLength = removedEntitiesHeaderSpan[1]; cursor += 4; if (removedEntitiesCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), removedEntitiesLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, removedEntitiesLength); UnpackEntityUtility.RemoveEntities(_game, _fromServer, removedEntitiesCount); cursor += removedEntitiesLength; } } #endregion #region removed components if ((flags & PackedDataFlags.RemovedComponents) == PackedDataFlags.RemovedComponents) { var removedComponentsHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var removedComponentsCount = removedComponentsHeaderSpan[0]; var removedComponentsLength = removedComponentsHeaderSpan[1]; cursor += 4; if (removedComponentsCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), removedComponentsLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, removedComponentsLength); UnpackEntityUtility.RemoveComponents(_game, _fromServer, removedComponentsCount); cursor += removedComponentsLength; } } #endregion #region changed components if ((flags & PackedDataFlags.ChangedComponents) == PackedDataFlags.ChangedComponents) { var changedComponentsHeaderSpan = new ReadOnlySpan <ushort>(IntPtr.Add(state, cursor).ToPointer(), 2); var changedComponentsCount = changedComponentsHeaderSpan[0]; var changedComponentsLength = changedComponentsHeaderSpan[1]; cursor += 4; if (changedComponentsCount > 0) { var dataSpan = new ReadOnlySpan <byte>(IntPtr.Add(state, cursor).ToPointer(), changedComponentsLength); _fromServer.Clear(); _fromServer.FromSpan(ref dataSpan, changedComponentsLength); UnpackEntityUtility.ChangeComponents(_game, _fromServer, changedComponentsCount); } } #endregion Marshal.FreeHGlobal(state); }
/// <summary> /// When overridden in a derived class, sets the position within the current stream. /// </summary> /// <returns> /// The new position within the current stream. /// </returns> public override long Seek(long offset, SeekOrigin origin) { BitBuffer.Clear(); return(BaseStream.Seek(offset, origin)); }
/// <summary> /// Datas the received. /// </summary> /// <param name="sender">Sender.</param> /// <param name="args">Arguments.</param> private static void DataReceived(object sender, DataReceivedEventArgs args) { Console.WriteLine("Received (" + string.Join <byte>(", ", args.Bytes) + ") from " + connection.EndPoint.ToString()); //Decode parse received data //Remove first byte (type) //https://stackoverflow.com/questions/31550484/faster-code-to-remove-first-elements-from-byte-array byte SendTypeBuffer = args.Bytes[0]; byte[] NewBufferReceiver = new byte[args.Bytes.Length - 1]; Array.Copy(args.Bytes, 1, NewBufferReceiver, 0, NewBufferReceiver.Length); //Check SendType if ((SendTypeBuffer == (byte)SendType.SENDTOALL) || (SendTypeBuffer == (byte)SendType.SENDTOOTHER)) { //Deserialize message using NetStack //Reset bit buffer for further reusing data.Clear(); data.FromArray(NewBufferReceiver, NewBufferReceiver.Length); byte TypeBuffer = data.ReadByte(); string OwnerPlayer = data.ReadString(); bool isKine = data.ReadBool(); uint IDObject = data.ReadUInt(); CompressedVector3 position = new CompressedVector3(data.ReadUInt(), data.ReadUInt(), data.ReadUInt()); CompressedQuaternion rotation = new CompressedQuaternion(data.ReadByte(), data.ReadShort(), data.ReadShort(), data.ReadShort()); //Read Vector3 Compress Velocity //ushort compressedVelocityX = HalfPrecision.Compress(speed); Vector3 VelocityReceived = new Vector3(HalfPrecision.Decompress(data.ReadUShort()), HalfPrecision.Decompress(data.ReadUShort()), HalfPrecision.Decompress(data.ReadUShort())); //Read Float InterpolationTime float InterpolationTime = HalfPrecision.Decompress(data.ReadUShort()); // Check if bit buffer is fully unloaded Console.WriteLine("Bit buffer is empty: " + data.IsFinished); //Decompress Vector and Quaternion //Create a new BoundedRange array for Vector3 position, each entry has bounds and precision BoundedRange[] worldBounds = new BoundedRange[3]; worldBounds[0] = new BoundedRange(-50f, 50f, 0.05f); // X axis worldBounds[1] = new BoundedRange(0f, 25f, 0.05f); // Y axis worldBounds[2] = new BoundedRange(-50f, 50f, 0.05f); // Z axis //Decompress position data Vector3 decompressedPosition = BoundedRange.Decompress(position, worldBounds); // Decompress rotation data Quaternion decompressedRotation = SmallestThree.Decompress(rotation); //Show DATA received if (DEBUG) { Console.WriteLine("ID RECEIVED: " + IDObject.ToString()); Console.WriteLine("TYPE RECEIVED: " + TypeBuffer.ToString()); Console.WriteLine("UID RECEIVED: " + OwnerPlayer); Console.WriteLine("IsKINE RECEIVED: " + isKine.ToString()); Console.WriteLine("POS RECEIVED: " + decompressedPosition.X.ToString() + ", " + decompressedPosition.Y.ToString() + ", " + decompressedPosition.Z.ToString()); Console.WriteLine("ROT RECEIVED: " + decompressedRotation.X.ToString() + ", " + decompressedRotation.Y.ToString() + ", " + decompressedRotation.Z.ToString() + ", " + decompressedRotation.W.ToString()); Console.WriteLine("VEL RECEIVED: " + VelocityReceived.X.ToString() + ", " + VelocityReceived.Y.ToString() + ", " + VelocityReceived.Z.ToString()); Console.WriteLine("INTERPOLATION TIME: " + InterpolationTime.ToString()); } if ((byte)PacketId.PLAYER_JOIN == TypeBuffer) { Console.WriteLine("Add new Player!"); //Code for new Player //Spawn something? YES //Using Dispatcher? NO //PlayerSpawn SendMessage(SendType.SENDTOOTHER, PacketId.PLAYER_SPAWN, 0, UID + ";" + AvatarName, true, lastPosition, lastRotation, VelocityDefaultZero, 0f); //TODO: Using Reliable UDP?? } else if ((byte)PacketId.OBJECT_MOVE == TypeBuffer) { Console.WriteLine("OBJECT MOVE"); } else if ((byte)PacketId.PLAYER_MOVE == TypeBuffer) { Console.WriteLine("PLAYER MOVE"); } else if ((byte)PacketId.PLAYER_SPAWN == TypeBuffer) { Console.WriteLine("PLAYER SPAWN"); } else if ((byte)PacketId.OBJECT_SPAWN == TypeBuffer) { Console.WriteLine("OBJECT SPAWN"); //Rez Object Received //RezObject(OwnerPlayer.Split(';')[1], OwnerPlayer.Split(';')[0], false); } else if ((byte)PacketId.OBJECT_UNSPAWN == TypeBuffer) { Console.WriteLine("OBJECT UNSPAWN"); //De Rez Object Received //DeRezObject(OwnerPlayer.Split(';')[1], OwnerPlayer.Split(';')[0], false, ObjectReceived.ID); } } else if (SendTypeBuffer == (byte)SendType.SENDTOSERVER) { //Deserialize message using NetStack //Reset bit buffer for further reusing data.Clear(); data.FromArray(NewBufferReceiver, NewBufferReceiver.Length); byte CommandTypeBuffer = data.ReadByte(); string Answer = data.ReadString(); // Check if bit buffer is fully unloaded Console.WriteLine("Bit buffer is empty: " + data.IsFinished); if ((byte)CommandType.LOGIN == CommandTypeBuffer) { if (Answer != String.Empty) { UID = Answer; //Set UID for Your Avatar ME //UnityMainThreadDispatcher.Instance().Enqueue(SetUIDInMainThread(HMessageReceived.Answer)); Console.WriteLine("UID RECEIVED: " + Answer); //PLAYER_JOIN MESSAGE (SENDTOOTHER) SendMessage(SendType.SENDTOOTHER, PacketId.PLAYER_JOIN, 0, UID + ";" + AvatarName, true, lastPosition, lastRotation, VelocityDefaultZero, 0f); //TO DO: Using Reliable UDP?? } else { Console.WriteLine("UID RECEIVED is EMPTY (NOT VALID PASSWORD): " + Answer); //Disconnect if (connection != null) { Console.WriteLine("DisConnecting from: " + connection.EndPoint.ToString()); connection.Close(); } } } else if ((byte)CommandType.DISCONNECTEDCLIENT == CommandTypeBuffer) { //Debug Disconnected UID Console.WriteLine("UID RECEIVED and TO DESTROY: " + Answer); } } args.Recycle(); }