Update ReadMe
This commit is contained in:
1 parent
392a33eb9e
commit
531fd2572f
1 file changed
+151
-57
@@ -13,94 +13,188 @@ Note: All datatypes that are sent to the server, The server needs to be aware of
|
|||||||
|
|
||||||
Create the server
|
Create the server
|
||||||
```c#
|
```c#
|
||||||
IMistoxServer serverobj = mServer.newServer( int Port, ServerMode mode )
|
ServerInterface serverobj = mServer.newServer( string serverName, int port )
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the client
|
Create the client
|
||||||
```c#
|
```c#
|
||||||
IMistoxServer serverobj = mServer.newClient( string HostNameOrIP, int Port )
|
ClientInterface clientobj = mServer.newClient( string HostNameOrIP, int Port )
|
||||||
```
|
```
|
||||||
|
|
||||||
Sending data
|
Sending data from the server
|
||||||
```c#
|
```c#
|
||||||
serverobj.Send( dynamic Object, SendType Speed )
|
serverobj.SendClient( string UserName, dynamic Object ) // Sent as a TCP packet to the client
|
||||||
|
serverobj.SendAllClients( dynamic Object ) // Sent as a TCP packet to all clients
|
||||||
```
|
```
|
||||||
|
|
||||||
Connected and Disconnected
|
Sending data from the client
|
||||||
|
```c#
|
||||||
|
clientobj.SendServer( dynamic Object ) // Sent as a TCP packet to the server
|
||||||
|
clientobj.SendClient( string UserName, dynamic Object ) // Sent as a UDP packet directly to the client
|
||||||
|
clientobj.SendAllClients( dynamic Object ) // Sent as a UDP packet directly to all clients
|
||||||
|
```
|
||||||
|
|
||||||
|
Wiring up the event handlers
|
||||||
|
|
||||||
|
Users Connecting and Disconnecting
|
||||||
```c#
|
```c#
|
||||||
|
|
||||||
serverobj.onConnected += OnConnected;
|
serverobj.onUserConnected += (TcpClientConnection connection) => {
|
||||||
serverobj.onDisconnected += OnDisconnected;
|
// When a new user joins the server this fires
|
||||||
void OnConnected( object Data, EventArgs e ){
|
};
|
||||||
// Sender and e are always null
|
|
||||||
// Put on connected funtions here
|
serverobj.onUserDisconnected += (TcpClientConnection connection) => {
|
||||||
// such as when connected spawn a player
|
// When a user leaves the server this fires
|
||||||
}
|
};
|
||||||
void OnDisconnected( object Data, EventArgs e ){
|
|
||||||
// Sender and e are always null
|
clientobj.onUserConnected += (UDPEndpoint remoteUser) => {
|
||||||
// Put on disconnected funtions here
|
// When a new user joins the server this fires
|
||||||
// such as when disconnected return to main menu
|
};
|
||||||
}
|
|
||||||
|
clientobj.onUserDisconnected += (UDPEndpoint remoteUser) => {
|
||||||
|
// When a user leaves the server this fires
|
||||||
|
};
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The client also gets the ability to see if the server disconnected
|
||||||
|
```c#
|
||||||
|
|
||||||
|
clientobj.onServerConnected += () => {
|
||||||
|
// When the client establishes a connection with the server
|
||||||
|
};
|
||||||
|
|
||||||
|
clientobj.onServerDisconnected += () => {
|
||||||
|
// fires if the connection drops
|
||||||
|
};
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Receiving data
|
Receiving data
|
||||||
```c#
|
```c#
|
||||||
|
|
||||||
serverobj.onSlowReceive += SlowReceivedData;
|
// When a packet is received from either the Server or another user this fires
|
||||||
serverobj.onFastReceive += FastReceivedData;
|
// 'data' here can be any function tagged mPacket
|
||||||
void SlowReceivedData( object Data, EventArgs e ){
|
// use this format as an example
|
||||||
if (Data is Datatype dt){ // Only works in Athoritative mode on server | will always work on client
|
serverobj.onDataReceived += (dynamic data) => {
|
||||||
|
switch (data as object) {
|
||||||
|
case UserConnectionPacket packet:
|
||||||
|
userConnected(packet);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
case UserDisconnectedPacket packet:
|
||||||
}
|
userDisconnected(packet);
|
||||||
void FastReceivedData( object Data, EventArgs e ){
|
break;
|
||||||
if (Data is Datatype dt){ // Only works in Athoritative mode on server | will always work on client
|
|
||||||
|
|
||||||
|
case null:
|
||||||
|
Console.WriteLine("Received a null packet.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLine($"Packet of type {data.GetType().Name} not accounted for");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
SendType *Enumeration
|
In order to send a packet you need to define the packet as an mPacket
|
||||||
|
an mPacket requires a unique ID, This ID allows the packet to be decyphered on the receving side
|
||||||
|
Therefore every mPacket requires a unique ID. The ID field is 8 bytes so the biggest number is 0xFF.
|
||||||
|
|
||||||
Where SlowUpdate is sent over TCP
|
By default the mPacket will work on both the server connection and the client connections. But due
|
||||||
|
to the limited function space you can reuse ID's if you map them out correcty because there are 2
|
||||||
And FastUpate is sent over UDP
|
packet scopes as shown below.
|
||||||
```c#
|
```c#
|
||||||
public enum SendType {
|
public enum PacketUsage {
|
||||||
SlowUpdate,
|
ClientToClient = 0x01, // Used only for Client To Client Connections
|
||||||
FastUpdate
|
ClientToServer = 0x10, // Used only for Server To Client and Client To Server connections
|
||||||
}
|
}
|
||||||
|
// ClientToServer packets are also used for ServerToClient connections as well
|
||||||
|
|
||||||
|
// If you would like to send a packet to both the clients and to the server you need to either use
|
||||||
|
// the base function or add the bitwise or. Some examples are listed below
|
||||||
|
|
||||||
|
[mPacket(0x01, PacketUsage.ClientToClient)] // Exclusivly for client to client usage
|
||||||
|
[mPacket(0x01, PacketUsage.ClientToServer)] // Exclusivly for client to server usage
|
||||||
|
// These 2 packets can exist at the same time becuase the scope is different even though the packet id is already used
|
||||||
|
|
||||||
|
[mPacket(0x02)] // This can be used for both connection types therefor the ID needs to be unique
|
||||||
|
[mPacket(0x03, PacketUsage.ClientToClient | PacketUsage.ClientToServer)] // Same as the line just before
|
||||||
```
|
```
|
||||||
|
|
||||||
ServerMode *Enumeration
|
## Full example to tie it all together
|
||||||
The Servermode tells the server if it should Deserialize examine then Reserialize the data passing through.
|
|
||||||
This can be useful to make sure data is
|
|
||||||
|
|
||||||
1 actually belonging to the server
|
|
||||||
|
|
||||||
2 the ability to keep track of objects within the server [ prevent cheating ]
|
|
||||||
|
|
||||||
This requires alot of overhead on the server though.
|
|
||||||
|
|
||||||
Passive doesnt use a serdes and instead just passes the data in and out
|
|
||||||
In this mode the server doesnt need to know data types
|
|
||||||
|
|
||||||
Athoritative will Deserialize and Serialize the data
|
|
||||||
Refer to the CLI/Program.CS for reference
|
|
||||||
In this mode the server needs to know the data types being sent
|
|
||||||
Therefore you need to put all your data classes into a library and and the library to both the application and the server
|
|
||||||
```c#
|
```c#
|
||||||
public enum ServerMode {
|
using System;
|
||||||
Passive,
|
using System.Collections.Generic;
|
||||||
Authoritative
|
using System.Threading.Tasks;
|
||||||
|
using Mistox;
|
||||||
|
using Mistox.Attributes;
|
||||||
|
using Mistox.Server;
|
||||||
|
|
||||||
|
[mPacket(0x01)]
|
||||||
|
class HelloPacket {
|
||||||
|
public string Name { get; set; } = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[mPacket(0x02, PacketUsage.ClientToServer)]
|
||||||
|
class GoodbyePacket {
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
class Main {
|
||||||
|
|
||||||
|
ServerInterface serverobj;
|
||||||
|
List<TcpClientConnection> connectedUsers = new List<TcpClientConnection>();
|
||||||
|
|
||||||
|
public async Task Main(){
|
||||||
|
serverobj = mServer.newServer( "serverName", 1234 );
|
||||||
|
serverobj.onDataReceived += ReceiveThread;
|
||||||
|
serverobj.onUserConnected += (TcpClientConnection user) => {
|
||||||
|
connectedUsers.Add(user);
|
||||||
|
};
|
||||||
|
serverobj.onUserDisconnected += (TcpClientConnection user) => {
|
||||||
|
connectedUsers.Add(user);
|
||||||
|
};
|
||||||
|
|
||||||
|
await serverobj.SendAllClients(new HelloPacket {
|
||||||
|
Name = "Jeffey"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveThread(dynamic data){
|
||||||
|
switch (data as object) {
|
||||||
|
case HelloPacket packet:
|
||||||
|
HelloWasCalled(packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GoodbyePacket packet:
|
||||||
|
GoodbyeWasCalled(packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLine($"Packet of type {data.GetType().Name} not accounted for");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HelloWasCalled(HelloPacket packet) {
|
||||||
|
connectedUsers[0].UserName = packet.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GoodbyeWasCalled(GoodbyePacket packet) {
|
||||||
|
foreach(var cur in connectedUsers) {
|
||||||
|
if (cur.UserName == packet.Name) {
|
||||||
|
connectedUsers.Remove(cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
Place all your networked data types into a library
|
|
||||||
Copy the library to the application and to the server
|
|
||||||
reference the library for the networked data types
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user