Пример #1
0
        public static void HandleEntityTeleport(IPacket packet, MultiPlayerClient client)
        {
            var teleport = (EntityTeleportPacket)packet;

            client.Trace.TraceData(TraceEventType.Warning, 0,
                                   $"server wants client to teleport entity {teleport.EntityId}, but we don't have an entity manager");
        }
Пример #2
0
        public static void HandleChunkPreamble(IPacket _packet, MultiPlayerClient client)
        {
            var packet = (ChunkPreamblePacket)_packet;
            var coords = new Coordinates2D(packet.X, packet.Z);

            client.World.SetChunk(coords, new Chunk(coords));
        }
Пример #3
0
        public async Task TestRequestResponseWithSockets()
        {
            var socketServer = new SocketServerNetworkProvider(8080);
            var server       = new MultiPlayerServer(socketServer);
            var client       = new MultiPlayerClient(new SocketClientNetworkProvider());

            await TestRequestResponse(server, socketServer.ServerInfo, client);
        }
Пример #4
0
        public async Task TestDeathmatchWithSockets()
        {
            var socketServer = new SocketServerNetworkProvider(8080);
            var server       = new MultiPlayerServer(socketServer);
            var client1      = new MultiPlayerClient(new SocketClientNetworkProvider());
            var client2      = new MultiPlayerClient(new SocketClientNetworkProvider());

            await TestDeathmatch(server, socketServer.ServerInfo, client1, client2, 500);
        }
Пример #5
0
        public static void HandlePositionAndLook(IPacket packet, MultiPlayerClient client)
        {
            var position = (SetPlayerPositionPacket)packet;

            client._Position = new Vector3((float)position.X, (float)position.Y, (float)position.Z);
            client.QueuePacket(position);
            client.LoggedIn = true;
            // TODO: Pitch and yaw
        }
Пример #6
0
        public static void HandleHandshake(IPacket packet, MultiPlayerClient client)
        {
            if (((HandshakeResponsePacket)packet).ConnectionHash != "-")
            {
                Console.WriteLine("Online mode is not supported");
                Process.GetCurrentProcess().Kill();
            }

            // TODO: Authentication
            client.QueuePacket(new LoginRequestPacket(PacketReader.Version, client.User.Username));
        }
        private MultiPlayerClient InitializeClient()
        {
            var client = new MultiPlayerClient(new SocketClientNetworkProvider());

            client.Disconnected.SubscribeOnce(OnMyClientDisconnected);
            client.EventRouter.Register <NewUserMessage>(OnOpponentArrived, gameLifetime);
            client.EventRouter.Register <LeftMessage>(OnOpponentLeft, gameLifetime);
            client.EventRouter.Register <BoundsMessage>(OnBoundsReceived, this);
            MainCharacter.MultiPlayerClient = client;
            return(client);
        }
Пример #8
0
        public async Task TestRequestResponseInProc()
        {
            var serverInfo = new ServerInfo()
            {
                Port = 8080, Server = "testserver"
            };
            var server = new MultiPlayerServer(new InProcServerNetworkProvider(serverInfo));
            var client = new MultiPlayerClient(new InProcClientNetworkProvider("client1"));

            await TestRequestResponse(server, serverInfo, client);
        }
Пример #9
0
        public async Task TestDeathmatchInProc()
        {
            var serverInfo = new ServerInfo()
            {
                Port = 8080, Server = "testserver"
            };
            var server  = new MultiPlayerServer(new InProcServerNetworkProvider(serverInfo));
            var client1 = new MultiPlayerClient(new InProcClientNetworkProvider("client1"));
            var client2 = new MultiPlayerClient(new InProcClientNetworkProvider("client2"));

            await TestDeathmatch(server, serverInfo, client1, client2, 100);
        }
Пример #10
0
        public static void HandleWindowItems(IPacket _packet, MultiPlayerClient client)
        {
            var packet = (WindowItemsPacket)_packet;

            if (packet.WindowID == 0)
            {
                client.Inventory.SetSlots(packet.Items);
            }
            else
            {
                client.CurrentWindow.SetSlots(packet.Items);
            }
        }
        private async Task ConnectToRemoteServer(ServerInfo serverInfo)
        {
            var delayedConnectingDialog = new DelayedWaitingPrompt();
            var connectingDialogTask    = ShowConnectingDialogDelayed(serverInfo, delayedConnectingDialog);
            Task <StartGameMessage> gameStartSignal;

            try
            {
                client          = InitializeClient();
                gameStartSignal = client.EventRouter.GetAwaitable <StartGameMessage>();
                await client.Connect(serverInfo).AsAwaitable();

                delayedConnectingDialog.PromptIsStillNeeded = false;
                await connectingDialogTask;
                await client.SendRequest(new UserInfoMessage()
                {
                    DisplayName = Environment.UserName
                }).AsAwaitable();
            }
            catch (Exception ex)
            {
                QueueAction(() => Dialog.ShowMessage("Failed to connect".ToRed()).Then(Cleanup));
                return;
            }
            finally
            {
                await delayedConnectingDialog.Cleanup();
            }

            var delayedWaitingForOtherPlayersDialogSignal = new DelayedWaitingPrompt();
            var waitingForOtherPlayersDialogTask          = ShowWaitingMessage("Waiting for other players...".ToConsoleString(), delayedWaitingForOtherPlayersDialogSignal);

            // If we got here then we are connected. Now we wait for the game to start
            var gameStartInfo = await gameStartSignal;

            delayedWaitingForOtherPlayersDialogSignal.PromptIsStillNeeded = false;
            await waitingForOtherPlayersDialogTask;
            await delayedWaitingForOtherPlayersDialogSignal.Cleanup();

            await RevealPlayers(gameStartInfo);

            QueueAction(() => ScenePanel.IsVisible = true);
            Sound.Play("Reload");
            var bgMusicHandle = await Sound.Play("BackgroundMusic").AsAwaitable();

            gameLifetime.OnDisposed(bgMusicHandle.Dispose);
            // wait for the game to end
            var gameOverMessage = await client.EventRouter.GetAwaitable <GameOverMessage>();

            ShowWinnerAndCleanup(gameOverMessage);
        }
Пример #12
0
        public static void HandleOpenWindowPacket(IPacket _packet, MultiPlayerClient client)
        {
            var     packet = (OpenWindowPacket)_packet;
            IWindow window = null;

            switch (packet.Type)
            {
            case 1:                     // Crafting bench window
                window = new CraftingBenchWindow(client.CraftingRepository, client.Inventory);
                break;
            }

            window.Id            = packet.WindowID;
            client.CurrentWindow = window;
        }
Пример #13
0
        public static void RegisterHandlers(MultiPlayerClient client)
        {
            client.RegisterPacketHandler(Constants.PacketIds.KeepAlive, HandleKeepAlive);
            client.RegisterPacketHandler(Constants.PacketIds.HandshakeResponse, HandleHandshake);
            client.RegisterPacketHandler(Constants.PacketIds.ChatMessage, HandleChatMessage);
            client.RegisterPacketHandler(Constants.PacketIds.SetPlayerPosition, HandlePositionAndLook);
            client.RegisterPacketHandler(Constants.PacketIds.LoginResponse, HandleLoginResponse);
            client.RegisterPacketHandler(Constants.PacketIds.UpdateHealth, HandleUpdateHealth);
            client.RegisterPacketHandler(Constants.PacketIds.TimeUpdate, HandleTimeUpdate);
            client.RegisterPacketHandler(Constants.PacketIds.EntityTeleport, HandleEntityTeleport);

            client.RegisterPacketHandler(Constants.PacketIds.ChunkPreamble, ChunkHandlers.HandleChunkPreamble);
            client.RegisterPacketHandler(Constants.PacketIds.ChunkData, ChunkHandlers.HandleChunkData);
            client.RegisterPacketHandler(Constants.PacketIds.BlockChange, ChunkHandlers.HandleBlockChange);
            client.RegisterPacketHandler(Constants.PacketIds.WindowItems, InventoryHandlers.HandleWindowItems);
            client.RegisterPacketHandler(Constants.PacketIds.SetSlot, InventoryHandlers.HandleSetSlot);
            client.RegisterPacketHandler(Constants.PacketIds.CloseWindow, InventoryHandlers.HandleCloseWindowPacket);
            client.RegisterPacketHandler(Constants.PacketIds.OpenWindow, InventoryHandlers.HandleOpenWindowPacket);
        }
Пример #14
0
        public static void HandleSetSlot(IPacket _packet, MultiPlayerClient client)
        {
            var     packet = (SetSlotPacket)_packet;
            IWindow window = null;

            if (packet.WindowID == 0)
            {
                window = client.Inventory;
            }
            else
            {
                window = client.CurrentWindow;
            }
            if (window != null)
            {
                if (packet.SlotIndex >= 0 && packet.SlotIndex < window.Length)
                {
                    window[packet.SlotIndex] = new ItemStack(packet.ItemId, packet.Count, packet.Metadata);
                }
            }
        }
Пример #15
0
        public static void HandleBlockChange(IPacket _packet, MultiPlayerClient client)
        {
            var           packet      = (BlockChangePacket)_packet;
            var           coordinates = new Coordinates3D(packet.X, packet.Y, packet.Z);
            Coordinates3D adjusted;
            IChunk        chunk;

            try
            {
                adjusted = client.World.World.FindBlockPosition(coordinates, out chunk);
            }
            catch (ArgumentException)
            {
                // Relevant chunk is not loaded - ignore packet
                return;
            }

            chunk.SetBlockID(adjusted, (byte)packet.BlockId);
            chunk.SetMetadata(adjusted, (byte)packet.Metadata);
            client.OnBlockChanged(new BlockChangeEventArgs(coordinates, new BlockDescriptor(),
                                                           new BlockDescriptor()));
            client.OnChunkModified(new ChunkEventArgs(new ReadOnlyChunk(chunk)));
        }
Пример #16
0
        public static void HandleChunkData(IPacket _packet, MultiPlayerClient client)
        {
            var    packet = (ChunkDataPacket)_packet;
            var    coords = new Coordinates3D(packet.X, packet.Y, packet.Z);
            var    data   = ZlibStream.UncompressBuffer(packet.CompressedData);
            IChunk chunk;
            var    adjustedCoords = client.World.World.FindBlockPosition(coords, out chunk);

            if (packet.Width == Chunk.Width &&
                packet.Height == Chunk.Height &&
                packet.Depth == Chunk.Depth)                // Fast path
            {
                // Chunk data offsets
                var metadataOffset = chunk.Data.Length;
                var lightOffset    = metadataOffset + chunk.Metadata.Length;
                var skylightOffset = lightOffset + chunk.BlockLight.Length;

                // Block IDs
                Buffer.BlockCopy(data, 0, chunk.Data, 0, chunk.Data.Length);
                // Block metadata
                if (metadataOffset < data.Length)
                {
                    Buffer.BlockCopy(data, metadataOffset,
                                     chunk.Metadata.Data, 0, chunk.Metadata.Data.Length);
                }
                // Block light
                if (lightOffset < data.Length)
                {
                    Buffer.BlockCopy(data, lightOffset,
                                     chunk.BlockLight.Data, 0, chunk.BlockLight.Data.Length);
                }
                // Sky light
                if (skylightOffset < data.Length)
                {
                    Buffer.BlockCopy(data, skylightOffset,
                                     chunk.SkyLight.Data, 0, chunk.SkyLight.Data.Length);
                }
            }
            else             // Slow path
            {
                int x = adjustedCoords.X, y = adjustedCoords.Y, z = adjustedCoords.Z;
                var fullLength   = packet.Width * packet.Height * packet.Depth; // Length of full sized byte section
                var nibbleLength = fullLength / 2;                              // Length of nibble sections
                for (var i = 0; i < fullLength; i++)                            // Iterate through block IDs
                {
                    chunk.SetBlockID(new Coordinates3D(x, y, z), data[i]);
                    y++;
                    if (y >= packet.Height)
                    {
                        y = 0;
                        z++;
                        if (z >= packet.Depth)
                        {
                            z = 0;
                            x++;
                            if (x >= packet.Width)
                            {
                                x = 0;
                            }
                        }
                    }
                }

                x = adjustedCoords.X;
                y = adjustedCoords.Y;
                z = adjustedCoords.Z;
                for (var i = fullLength; i < nibbleLength; i++)                 // Iterate through metadata
                {
                    var m = data[i];
                    chunk.SetMetadata(new Coordinates3D(x, y, z), (byte)(m & 0xF));
                    chunk.SetMetadata(new Coordinates3D(x, y + 1, z), (byte)(m & (0xF0 << 8)));
                    y += 2;
                    if (y >= packet.Height)
                    {
                        y = 0;
                        z++;
                        if (z >= packet.Depth)
                        {
                            z = 0;
                            x++;
                            if (x >= packet.Width)
                            {
                                x = 0;
                            }
                        }
                    }
                }

                // TODO: Lighting
            }

            chunk.UpdateHeightMap();
            chunk.TerrainPopulated = true;
            client.OnChunkLoaded(new ChunkEventArgs(new ReadOnlyChunk(chunk)));
        }
Пример #17
0
 public static void HandleUpdateHealth(IPacket packet, MultiPlayerClient client)
 {
     client.Health = ((UpdateHealthPacket)packet).Health;
 }
Пример #18
0
 private static void HandleKeepAlive(IPacket packet, MultiPlayerClient client)
 {
     // TODO
 }
Пример #19
0
        private async Task TestRequestResponse(MultiPlayerServer server, ServerInfo serverInfo, MultiPlayerClient client)
        {
            await server.OpenForNewConnections().AsAwaitable();

            Console.WriteLine("server is listening");
            await client.Connect(serverInfo).AsAwaitable();


            try
            {
                var sw       = Stopwatch.StartNew();
                var response = await client.SendRequest(new PingMessage(), timeout : TimeSpan.FromDays(1)).AsAwaitable();

                sw.Stop();
                Console.WriteLine("ping took " + sw.ElapsedMilliseconds + " ms");
            }
            catch (Exception ex)
            {
                throw;
            }



            try
            {
                await client.SendRequest(new PingMessage()
                {
                    Delay = 300
                }, timeout : TimeSpan.FromSeconds(.1)).AsAwaitable();

                Assert.Fail("A timeout exception should have been thrown");
            }
            catch (PromiseWaitException ex)
            {
                Assert.AreEqual(1, ex.InnerExceptions.Count);
                Assert.IsTrue(ex.InnerException is TimeoutException);
            }

            client.Dispose();
            server.Dispose();
        }
Пример #20
0
 public static void HandleChatMessage(IPacket packet, MultiPlayerClient client)
 {
     client.OnChatMessage(new ChatMessageEventArgs(((ChatMessagePacket)packet).Message));
 }
Пример #21
0
 public static void HandleCloseWindowPacket(IPacket _packet, MultiPlayerClient client)
 {
     client.CurrentWindow = null;
 }
Пример #22
0
 public static void HandleLoginResponse(IPacket packet, MultiPlayerClient client)
 {
     client.EntityId = ((LoginResponsePacket)packet).EntityId;
     client.QueuePacket(new PlayerGroundedPacket());
 }
Пример #23
0
        private async Task TestDeathmatch(MultiPlayerServer server, ServerInfo serverInfo, MultiPlayerClient client1, MultiPlayerClient client2, int delayMs)
        {
            Exception undeliverableException = null;
            Exception deathmatchException    = null;

            server.Undeliverable.SubscribeForLifetime((args) => undeliverableException = args.Exception, server);

            var deathmatch = new Deathmatch(new MultiPlayerContestOptions()
            {
                MaxPlayers = 2,
                Server     = server
            });

            deathmatch.OrchestrationFailed.SubscribeOnce((ex) => deathmatchException = ex);

            // the game starts
            await deathmatch.Start();

            // both clients start waiting for the start of the game
            var client1StartTask = client1.EventRouter.GetAwaitable <StartGameMessage>();
            var client2StartTask = client2.EventRouter.GetAwaitable <StartGameMessage>();

            // both clients get notified of each other's presence
            var client1SeesClient2Task = client1.EventRouter.GetAwaitable <NewUserMessage>();
            var client2SeesClient1Task = client2.EventRouter.GetAwaitable <NewUserMessage>();

            // both clients connect, which should trigger the start of the game
            await client1.Connect(serverInfo).AsAwaitable();

            Console.WriteLine("client 1 connected");
            await client2.Connect(serverInfo).AsAwaitable();

            Console.WriteLine("client 2 connected");

            // make sure both clients got the start event
            await client1StartTask;
            await client2StartTask;

            await client1SeesClient2Task;
            await client2SeesClient1Task;

            Assert.AreEqual(client2.ClientId, client1SeesClient2Task.Result.NewUserId);
            Assert.AreEqual(client1.ClientId, client2SeesClient1Task.Result.NewUserId);

            var client1GameOverTask = client1.EventRouter.GetAwaitable <GameOverMessage>();
            var client2GameOverTask = client2.EventRouter.GetAwaitable <GameOverMessage>();

            var response = await client1.SendRequest(new DamageMessage()
            {
                DamagedClient = client2.ClientId,
                NewHP         = 0
            }, timeout : TimeSpan.FromDays(1)).AsAwaitable();

            // make sure both clients got the game over event event
            await Task.WhenAll(client1GameOverTask, client2GameOverTask);

            Assert.AreEqual(client1.ClientId, client1GameOverTask.Result.WinnerId);
            Assert.AreEqual(client1.ClientId, client2GameOverTask.Result.WinnerId);

            client1.Dispose();
            client2.Dispose();
            server.Dispose();
            Assert.IsTrue(deathmatch.IsExpired);
            Assert.IsNull(undeliverableException);
            Assert.IsNull(deathmatchException);
        }
Пример #24
0
        public static void HandleTimeUpdate(IPacket packet, MultiPlayerClient client)
        {
            var time = ((TimeUpdatePacket)packet).Time / 20.0;

            client.World.World.BaseTime = DateTime.UtcNow - TimeSpan.FromSeconds(time);
        }