Update ReadMe

This commit is contained in:
derek committed 2026-07-03 17:46:22 -07:00
1 parent 392a33eb9e
commit 531fd2572f
1 file changed
+151 -57
+151 -57
View File
@@ -13,94 +13,188 @@ Note: All datatypes that are sent to the server, The server needs to be aware of
Create the server
```c#
IMistoxServer serverobj = mServer.newServer( int Port, ServerMode mode )
ServerInterface serverobj = mServer.newServer( string serverName, int port )
```
Create the client
```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#
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#
serverobj.onConnected += OnConnected;
serverobj.onDisconnected += OnDisconnected;
void OnConnected( object Data, EventArgs e ){
// Sender and e are always null
// Put on connected funtions here
// such as when connected spawn a player
}
void OnDisconnected( object Data, EventArgs e ){
// Sender and e are always null
// Put on disconnected funtions here
// such as when disconnected return to main menu
}
serverobj.onUserConnected += (TcpClientConnection connection) => {
// When a new user joins the server this fires
};
serverobj.onUserDisconnected += (TcpClientConnection connection) => {
// When a user leaves the server this fires
};
clientobj.onUserConnected += (UDPEndpoint remoteUser) => {
// When a new user joins the server this fires
};
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
```c#
serverobj.onSlowReceive += SlowReceivedData;
serverobj.onFastReceive += FastReceivedData;
void SlowReceivedData( object Data, EventArgs e ){
if (Data is Datatype dt){ // Only works in Athoritative mode on server | will always work on client
// When a packet is received from either the Server or another user this fires
// 'data' here can be any function tagged mPacket
// use this format as an example
serverobj.onDataReceived += (dynamic data) => {
switch (data as object) {
case UserConnectionPacket packet:
userConnected(packet);
break;
}
}
void FastReceivedData( object Data, EventArgs e ){
if (Data is Datatype dt){ // Only works in Athoritative mode on server | will always work on client
case UserDisconnectedPacket packet:
userDisconnected(packet);
break;
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
And FastUpate is sent over UDP
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
packet scopes as shown below.
```c#
public enum SendType {
SlowUpdate,
FastUpdate
public enum PacketUsage {
ClientToClient = 0x01, // Used only for Client To Client Connections
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
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
## Full example to tie it all together
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#
public enum ServerMode {
Passive,
Authoritative
using System;
using System.Collections.Generic;
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