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"); }
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)); }
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); }
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); }
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 }
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); }
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); }
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); }
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); }
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; }
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); }
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); } } }
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))); }
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))); }
public static void HandleUpdateHealth(IPacket packet, MultiPlayerClient client) { client.Health = ((UpdateHealthPacket)packet).Health; }
private static void HandleKeepAlive(IPacket packet, MultiPlayerClient client) { // TODO }
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(); }
public static void HandleChatMessage(IPacket packet, MultiPlayerClient client) { client.OnChatMessage(new ChatMessageEventArgs(((ChatMessagePacket)packet).Message)); }
public static void HandleCloseWindowPacket(IPacket _packet, MultiPlayerClient client) { client.CurrentWindow = null; }
public static void HandleLoginResponse(IPacket packet, MultiPlayerClient client) { client.EntityId = ((LoginResponsePacket)packet).EntityId; client.QueuePacket(new PlayerGroundedPacket()); }
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); }
public static void HandleTimeUpdate(IPacket packet, MultiPlayerClient client) { var time = ((TimeUpdatePacket)packet).Time / 20.0; client.World.World.BaseTime = DateTime.UtcNow - TimeSpan.FromSeconds(time); }