Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Networking Enhancements #4

Merged
merged 4 commits into from
Jul 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions ClientTester/MultiplayerClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@ public MultiplayerClient(String playerId)
{
loadedChunks = new LoadedChunks();
chunkAwarePacketReceiver = new ChunkAwarePacketReceiver(loadedChunks);
client = new TcpClient(chunkAwarePacketReceiver);
client = new TcpClient(chunkAwarePacketReceiver, true);
PacketSender = new PacketSender(client, multiplayerObjectManager);
PacketSender.PlayerId = playerId;
}

public void Start(String ip)
{
client.Start(ip);
PacketSender.Active = true;
PacketSender.Authenticate();
if (client.isConnected())
{
PacketSender.Active = true;
PacketSender.Authenticate();
}
}
}
}
71 changes: 59 additions & 12 deletions NitroxClient/Communication/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,53 @@ public class TcpClient
private ChunkAwarePacketReceiver packetReceiver;
private const int port = 11000;
private Connection connection;
private bool testClient = false;

public TcpClient(ChunkAwarePacketReceiver packetManager)
{
this.packetReceiver = packetManager;
}

public TcpClient(ChunkAwarePacketReceiver packetManager, bool testClient)
{
this.packetReceiver = packetManager;
this.testClient = testClient;
}

public void Start(String ip)
{
IPAddress ipAddress = IPAddress.Parse(ip);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
try
{
IPAddress ipAddress = IPAddress.Parse(ip);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connection = new Connection(socket);

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connection = new Connection(socket);
socket.Connect(remoteEP);

socket.Connect(remoteEP);
if (!socket.Connected)
{
outputMessage("Unable to connect to server.");
throw new InvalidOperationException("Socket could not connect.");
}
else
{
outputMessage("Connected to server.");
}

if(!socket.Connected)
connection.BeginReceive(new AsyncCallback(DataReceived));
}
catch (Exception e)
{
throw new InvalidOperationException("Socket could not connect.");
outputMessage("Unable to connect to server");
}

connection.BeginReceive(new AsyncCallback(DataReceived));
}

public void Close()
public void Stop()
{
connection.Close();
connection.Close(); // Server will clean up pretty quickly
outputMessage("Disconnected from server.");
}

private void DataReceived(IAsyncResult ar)
Expand All @@ -54,7 +74,14 @@ private void DataReceived(IAsyncResult ar)
packetReceiver.PacketReceived(packet);
}

connection.BeginReceive(new AsyncCallback(DataReceived));
if (connection.Open)
{
connection.BeginReceive(new AsyncCallback(DataReceived));
} else

This comment was marked as abuse.

{
Console.WriteLine("Error reading data from server");
Stop();
}
}

public void Send(Packet packet)
Expand All @@ -66,5 +93,25 @@ public void PacketSentSuccessful(IAsyncResult ar)
{

}

public bool isConnected()
{
if (connection == null)
{
return false;
}
return connection.Open;
}

private void outputMessage(String msg)
{
if (testClient)

This comment was marked as abuse.

{
Console.WriteLine(msg);
} else
{
ErrorMessage.AddMessage(msg);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using NitroxClient.Communication.Packets.Processors.Base;
using NitroxClient.GameLogic;
using NitroxModel.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NitroxClient.Communication.Packets.Processors
{
class DisconnectProcessor : GenericPacketProcessor<Disconnect>
{
private PlayerGameObjectManager playerGameObjectManager;

public DisconnectProcessor(PlayerGameObjectManager playerGameObjectManager)
{
this.playerGameObjectManager = playerGameObjectManager;
}

public override void Process(Disconnect disconnect)
{
playerGameObjectManager.RemovePlayerGameObject(disconnect.PlayerId);
}
}
}
8 changes: 8 additions & 0 deletions NitroxClient/GameLogic/PlayerGameObjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,13 @@ private GameObject createOtherPlayer(String playerId)
{
return GameObject.CreatePrimitive(PrimitiveType.Sphere);
}

public void RemovePlayerGameObject(String playerId)
{
GameObject player = gameObjectByPlayerId[playerId];
player.SetActive(false);
GameObject.DestroyImmediate(player);
gameObjectByPlayerId.Remove(playerId);
}
}
}
42 changes: 35 additions & 7 deletions NitroxClient/MonoBehaviours/Multiplayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ namespace NitroxClient.MonoBehaviours
public class Multiplayer : MonoBehaviour
{
private static readonly String DEFAULT_IP_ADDRESS = "127.0.0.1";

public static bool isActive = false;

public static PacketSender PacketSender;
private static LoadedChunks loadedChunks;
private static TcpClient client;
private static ChunkAwarePacketReceiver chunkAwarePacketReceiver;
private static bool hasLoadedMonoBehaviors;

private static PlayerGameObjectManager playerGameObjectManager = new PlayerGameObjectManager();
private static MultiplayerObjectManager multiplayerObjectManager = new MultiplayerObjectManager();
Expand All @@ -30,6 +30,7 @@ public class Multiplayer : MonoBehaviour
{typeof(BeginItemConstruction), new BeginItemConstructionProcessor() },
{typeof(ChatMessage), new ChatMessageProcessor() },
{typeof(ConstructionAmountChanged), new ConstructionAmountChangedProcessor() },
{typeof(Disconnect), new DisconnectProcessor(playerGameObjectManager) },
{typeof(DroppedItem), new DroppedItemProcessor(multiplayerObjectManager) },
{typeof(Movement), new MovementProcessor(playerGameObjectManager) },
{typeof(PickupItem), new PickupItemProcessor() },
Expand All @@ -40,6 +41,7 @@ public class Multiplayer : MonoBehaviour
public void Awake()
{
DevConsole.RegisterConsoleCommand(this, "mplayer", false);
DevConsole.RegisterConsoleCommand(this, "disconnect", false);

loadedChunks = new LoadedChunks();
chunkAwarePacketReceiver = new ChunkAwarePacketReceiver(loadedChunks);
Expand All @@ -49,7 +51,7 @@ public void Awake()

public void Update()
{
if (isActive)
if (client != null && client.isConnected())
{
ProcessPackets();
}
Expand All @@ -75,7 +77,10 @@ public void ProcessPackets()

public void OnConsoleCommand_mplayer(NotificationCenter.Notification n)
{
if (n != null && n.data != null && n.data.Count > 0)
if (client.isConnected())
{
ErrorMessage.AddMessage("Already connected to a server");
} else if (n != null && n.data != null && n.data.Count > 0)
{
PacketSender.PlayerId = (string)n.data[0];

Expand All @@ -88,7 +93,17 @@ public void OnConsoleCommand_mplayer(NotificationCenter.Notification n)

StartMultiplayer(ip);
InitMonoBehaviours();
isActive = true;
} else
{
ErrorMessage.AddMessage("Command syntax: mplayer USERNAME [SERVERIP]");
}
}

public void OnConsoleCommand_disconnect(NotificationCenter.Notification n)
{
if (n != null)
{
StopMultiplayer(); // TODO: More than just disconnect (clean up injections or something)
}
}

Expand All @@ -98,11 +113,24 @@ private void StartMultiplayer(String ipAddress)
PacketSender.Active = true;
PacketSender.Authenticate();
}

private void StopMultiplayer()
{
if (client.isConnected())
{
client.Stop();
PacketSender.Active = false;
}
}

public void InitMonoBehaviours()
{
this.gameObject.AddComponent<Chat>();
this.gameObject.AddComponent<PlayerMovement>();
if (!hasLoadedMonoBehaviors)
{
this.gameObject.AddComponent<Chat>();
this.gameObject.AddComponent<PlayerMovement>();
hasLoadedMonoBehaviors = true;
}
}

public static void AddChunk(Vector3 chunk, MonoBehaviour mb)
Expand Down
1 change: 1 addition & 0 deletions NitroxClient/NitroxClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<Compile Include="Communication\Packets\Processors\BeginItemConstructionProcessor.cs" />
<Compile Include="Communication\Packets\Processors\Base\GenericPacketProcessor.cs" />
<Compile Include="Communication\Packets\Processors\ConstructorBeginCraftingProcessor.cs" />
<Compile Include="Communication\Packets\Processors\DisconnectProcessor.cs" />
<Compile Include="Communication\Packets\Processors\DroppedItemProcessor.cs" />
<Compile Include="Communication\Packets\Processors\VehicleMovementProcessor.cs" />
<Compile Include="Communication\Packets\Processors\PickupItemProcessor.cs" />
Expand Down
1 change: 1 addition & 0 deletions NitroxModel/NitroxModel.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<Compile Include="DataStructures\Quaternion.cs" />
<Compile Include="DataStructures\ServerModel\VehicleModel.cs" />
<Compile Include="Packets\ConstructorBeginCrafting.cs" />
<Compile Include="Packets\Disconnect.cs" />
<Compile Include="Packets\VehicleMovement.cs" />
<Compile Include="Tcp\MessageBuffer.cs" />
<Compile Include="DataStructures\TimedQueue.cs" />
Expand Down
14 changes: 14 additions & 0 deletions NitroxModel/Packets/Disconnect.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NitroxModel.Packets
{
[Serializable]
public class Disconnect : Packet
{

This comment was marked as abuse.

public Disconnect(String playerId) : base(playerId) {}
}
}
41 changes: 35 additions & 6 deletions NitroxModel/Tcp/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class Connection
public String PlayerId { get; set; }
private Socket Socket;
private MessageBuffer MessageBuffer;
public Boolean Open { get; private set; }
public bool Open { get; private set; }

public Connection(Socket socket)
{
Expand All @@ -31,7 +31,16 @@ public void BeginReceive(AsyncCallback callback)

public IEnumerable<Packet> GetPacketsFromRecievedData(IAsyncResult ar)
{
int bytesRead = Socket.EndReceive(ar);
int bytesRead = 0;
try
{
bytesRead = Socket.EndReceive(ar);
}
catch (SocketException se)
{
Console.WriteLine("Error reading data from socket");
Open = false;
}

if (bytesRead > 0)
{
Expand All @@ -42,20 +51,40 @@ public IEnumerable<Packet> GetPacketsFromRecievedData(IAsyncResult ar)
}
else
{
Console.WriteLine("No data found from socket, disconnecting");
Open = false;
}
}

public void SendPacket(Packet packet, AsyncCallback callback)
{
byte[] packetData = packet.SerializeWithHeaderData();
Socket.BeginSend(packetData, 0, packetData.Length, 0, callback, Socket);
if (Open) // Can remove check if able to unload Mono behaviors
{
byte[] packetData = packet.SerializeWithHeaderData();
try
{
Socket.BeginSend(packetData, 0, packetData.Length, 0, callback, Socket);
}
catch (SocketException se)
{
Console.WriteLine("Error sending packet");
Open = false;
}
}
}

public void Close()
{
Socket.Shutdown(SocketShutdown.Both);
Socket.Close();
Open = false;
try
{
Socket.Shutdown(SocketShutdown.Both);
Socket.Close();
}
catch (Exception e)
{
Console.WriteLine("Error closing socket -- probably already closed");
}
}
}
}
Loading