- Complete networking aspect
- only TCP, works has been tested - Commented out Lists and replaced with arrays, the way the list was working it wouldn't have worked, if you can figure out how to make it work feel free to fix it up. - TODO: When user types exit, the game object becomes useless, I need a Reset function of some kind to reset it for when a new player comes in to reuse that player object. - TODO: Encryption - TODO: Fix main person so they have admin commands like list, restart instead of a game with the main server. (ATM Just like that for testing, but now you can test with telnet client)
This commit is contained in:
parent
c965d5e97a
commit
281fe4b320
8 changed files with 120 additions and 384 deletions
|
@ -54,10 +54,10 @@ namespace MUDGame
|
|||
|
||||
//Player must be instanced AFTER BuildRealms as it needs Game.InitialRealm.InitialZone.InitialRoom
|
||||
//property so that it can set it's starting room correctly.
|
||||
player = new BaseCharacter(game);
|
||||
player = new BaseCharacter(game,true);
|
||||
//Add the player to the game.
|
||||
//Note once the server is fully implemented the player will be generated automatically by Game.
|
||||
game.PlayerCollection.Add(player);
|
||||
//game.PlayerCollection.Add(player);
|
||||
|
||||
//Send game info to player
|
||||
Console.WriteLine(game.GameTitle);
|
||||
|
|
|
@ -25,13 +25,10 @@ namespace MudEngine.Commands
|
|||
{
|
||||
if (player.IsAdmin)
|
||||
{
|
||||
for (int i = 0; i < player.Game.PlayerCollection.Count; i++)
|
||||
for (int i = 0; i < player.Game.PlayerCollection./*Count*/Length; i++)
|
||||
player.Game.PlayerCollection[i].Save(player.Game.PlayerCollection[i].Name + ".dat");
|
||||
player.Game.Server.EndServer();
|
||||
if (player.Game.ServerType == ProtocolType.Tcp)
|
||||
player.Game.Server.InitializeTCP(555, ref player.Game.PlayerCollection);
|
||||
else
|
||||
player.Game.Server.InitializeUDP(555, ref player.Game.PlayerCollection);
|
||||
player.Game.Server.Initialize(555, ref player.Game.PlayerCollection);
|
||||
return new CommandResults("Server Restarted.");
|
||||
}
|
||||
return new CommandResults("Access Denied.");
|
||||
|
|
|
@ -170,7 +170,7 @@ namespace MudEngine.GameManagement
|
|||
CurrencyList = new List<Currency>();
|
||||
scriptEngine = new Scripting.ScriptEngine();
|
||||
RealmCollection = new List<Realm>();
|
||||
PlayerCollection = new List<BaseCharacter>();
|
||||
//PlayerCollection = new List<BaseCharacter>();
|
||||
|
||||
GameTitle = "New Game";
|
||||
_Filename = "Game.xml";
|
||||
|
@ -199,7 +199,7 @@ namespace MudEngine.GameManagement
|
|||
{
|
||||
Scripting.GameObject obj = new Scripting.GameObject();
|
||||
obj = scriptEngine.GetObject(t.Name);
|
||||
PlayerCollection.Add((BaseCharacter)obj.Instance);
|
||||
//PlayerCollection.Add((BaseCharacter)obj.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,8 @@ namespace MudEngine.GameManagement
|
|||
}
|
||||
|
||||
//TODO: This should be internal only; C# property using get; internal set; so only MudEngine.dll may edit this collection
|
||||
public List<BaseCharacter> PlayerCollection;
|
||||
//public List<BaseCharacter> PlayerCollection;
|
||||
public BaseCharacter[] PlayerCollection;
|
||||
|
||||
public MudEngine.Networking.Server Server { get; internal set; }
|
||||
public ProtocolType ServerType = ProtocolType.Tcp;
|
||||
|
@ -305,8 +306,12 @@ namespace MudEngine.GameManagement
|
|||
|
||||
private void StartServer()
|
||||
{
|
||||
//PlayerCollection = new List<BaseCharacter>(MaximumPlayers);
|
||||
PlayerCollection = new BaseCharacter[MaximumPlayers];
|
||||
for (int i = 0; i < MaximumPlayers; i++)
|
||||
PlayerCollection[i] = new BaseCharacter(this);
|
||||
Server = new Networking.Server();
|
||||
Server.InitializeTCP(ServerPort, ref PlayerCollection);
|
||||
Server.Initialize(ServerPort, ref PlayerCollection);
|
||||
Server.Start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ using MudEngine.GameObjects;
|
|||
using MudEngine.GameObjects.Environment;
|
||||
using MudEngine.GameObjects.Items;
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace MudEngine.GameObjects.Characters
|
||||
{
|
||||
public class BaseCharacter : BaseObject
|
||||
|
@ -31,15 +34,21 @@ namespace MudEngine.GameObjects.Characters
|
|||
/// </summary>
|
||||
public Boolean IsAdmin { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets if this player is active.
|
||||
/// </summary>
|
||||
public Boolean IsActive { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a reference to the currently running game.
|
||||
/// </summary>
|
||||
public Game Game { get; private set; }
|
||||
|
||||
public BaseCharacter(Game game)
|
||||
public BaseCharacter(Game game,bool admin = false)
|
||||
{
|
||||
Game = game;
|
||||
IsAdmin = true;
|
||||
IsAdmin = admin;
|
||||
IsActive = false;
|
||||
CurrentRoom = game.InitialRealm.InitialZone.InitialRoom;
|
||||
}
|
||||
|
||||
|
@ -89,12 +98,44 @@ namespace MudEngine.GameObjects.Characters
|
|||
return "";
|
||||
}
|
||||
|
||||
public void Initialize(ref MudEngine.Networking.ClientSocket rcs)
|
||||
internal void Initialize()
|
||||
{
|
||||
CurrentRoom = Game.InitialRealm.InitialZone.InitialRoom;
|
||||
sock = rcs;
|
||||
}
|
||||
|
||||
public MudEngine.Networking.ClientSocket sock;
|
||||
IsActive = true;
|
||||
}
|
||||
internal void Receive(byte[] data)
|
||||
{
|
||||
// convert that data to string
|
||||
String str;
|
||||
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
||||
str = enc.GetString(data);
|
||||
// execute, and get result
|
||||
str = ExecuteCommand(str);
|
||||
// convert the result back to bytes and send it back
|
||||
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
|
||||
Send(encoding.GetBytes(str));
|
||||
if (!Game.IsRunning)
|
||||
Clear();
|
||||
}
|
||||
internal void Send(byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
client.Send(data);
|
||||
}
|
||||
catch (Exception) // error, connection failed: close client
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
internal void Clear()
|
||||
{
|
||||
// TODO: Save();
|
||||
IsActive = false;
|
||||
client.Close();
|
||||
// TODO: Reset game so it can be used again
|
||||
}
|
||||
internal Socket client;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,9 +72,7 @@
|
|||
<Compile Include="GameObjects\Environment\Zone.cs" />
|
||||
<Compile Include="GameObjects\Items\BaseItem.cs" />
|
||||
<Compile Include="GameObjects\Currency.cs" />
|
||||
<Compile Include="Networking\ClientSocket.cs" />
|
||||
<Compile Include="Networking\Server.cs" />
|
||||
<Compile Include="Networking\ServerSocket.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Scripting\GameObject.cs" />
|
||||
<Compile Include="Scripting\GameObjectCollection.cs" />
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
// TODO: Make ClientSocket a friend of ServerSocket so I can make sock and type private
|
||||
// other, havn't thought of what else I need
|
||||
|
||||
namespace MudEngine.Networking
|
||||
{
|
||||
public class ClientSocket
|
||||
{
|
||||
public ClientSocket()
|
||||
{
|
||||
type = 0;
|
||||
used = false;
|
||||
}
|
||||
~ClientSocket()
|
||||
{
|
||||
type = 0;
|
||||
used = false;
|
||||
}
|
||||
public int Send(byte[] ba)
|
||||
{
|
||||
try
|
||||
{
|
||||
sock.Send(ba);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int Receive(byte[] ba)
|
||||
{
|
||||
try
|
||||
{
|
||||
sock.Receive(ba);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int CleanUp()
|
||||
{
|
||||
try
|
||||
{
|
||||
sock.Disconnect(true);
|
||||
sock.Close();
|
||||
sock.Dispose();
|
||||
type = 0;
|
||||
used = false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public ProtocolType type;
|
||||
public IPAddress ip;
|
||||
public Socket sock;
|
||||
public bool used;
|
||||
}
|
||||
}
|
|
@ -21,129 +21,110 @@ namespace MudEngine.Networking
|
|||
public Server()
|
||||
{
|
||||
stage = 0;
|
||||
server = new ServerSocket();
|
||||
port = 0;
|
||||
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
}
|
||||
~Server()
|
||||
{
|
||||
stage = 0;
|
||||
if (server.type == ProtocolType.Tcp)
|
||||
{
|
||||
for (int i = 0; i < numberOfClients; i++)
|
||||
clients[i].CleanUp();
|
||||
numberOfClients = 0;
|
||||
}
|
||||
server.CleanUp();
|
||||
port = 0;
|
||||
}
|
||||
public bool InitializeTCP(int port, ref List<BaseCharacter> pbs)
|
||||
public bool Initialize(int p, ref /*List<BaseCharacter>*/BaseCharacter[] pbs)
|
||||
{
|
||||
if (stage != 0)
|
||||
return false;
|
||||
if (server.Initialize(port, ProtocolType.Tcp) < 0)
|
||||
if (p <= 0)
|
||||
return false;
|
||||
|
||||
numberOfClients = pbs.Count;
|
||||
clients = new ClientSocket[pbs.Count];
|
||||
clientThreads = new Thread[pbs.Count];
|
||||
port = p;
|
||||
clientThreads = new Thread[pbs./*Capacity*/Length];
|
||||
players = pbs;
|
||||
|
||||
stage++;
|
||||
return true;
|
||||
}
|
||||
public bool InitializeUDP(int port, ref List<BaseCharacter> pbs)
|
||||
{
|
||||
if (stage != 0)
|
||||
return false;
|
||||
if (server.Initialize(port, ProtocolType.Udp) < 0)
|
||||
return false;
|
||||
|
||||
players = pbs;
|
||||
|
||||
stage++;
|
||||
return true;
|
||||
}
|
||||
public bool Start()
|
||||
{
|
||||
if (stage != 1)
|
||||
return false;
|
||||
if (server.Start() < 0)
|
||||
return false;
|
||||
if (server.Bind() < 0)
|
||||
return false;
|
||||
if (server.type == ProtocolType.Tcp)
|
||||
if (server.Listen() < 0)
|
||||
try
|
||||
{
|
||||
if (stage != 1)
|
||||
return false;
|
||||
stage++;
|
||||
serverThread = new Thread(ServerThread);
|
||||
serverThread.Start();
|
||||
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
|
||||
server.Bind(ipep);
|
||||
server.Listen(10);
|
||||
stage++;
|
||||
serverThread = new Thread(ServerThread);
|
||||
serverThread.Start();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public void EndServer()
|
||||
{
|
||||
stage = 0;
|
||||
serverThread.Abort();
|
||||
|
||||
if (server.type == ProtocolType.Tcp)
|
||||
{
|
||||
for (int i = 0; i < numberOfClients; i++)
|
||||
clients[i].CleanUp();
|
||||
numberOfClients = 0;
|
||||
}
|
||||
server.CleanUp();
|
||||
server.Close();
|
||||
}
|
||||
/*
|
||||
* ServerThread, if UDP: Accepts messages(ReceiveFrom) and sends in correspondence to the correct player
|
||||
* if TCP: Accepts connection and opens a separate thread to receive a data stream between the clien
|
||||
*/
|
||||
private void ServerThread()
|
||||
{
|
||||
if (server.type == ProtocolType.Udp)
|
||||
while (stage == 2)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
while (stage == 2)
|
||||
int sub = -1;
|
||||
do
|
||||
{
|
||||
int sub = -1;
|
||||
do
|
||||
for (int i = 0; i < players./*Count*/Length; i++)
|
||||
{
|
||||
for (int i = 0; i < numberOfClients; i++)
|
||||
if (!players[i].IsActive)
|
||||
{
|
||||
if (!clients[i].used)
|
||||
{
|
||||
sub = i;
|
||||
break;
|
||||
}
|
||||
sub = i;
|
||||
break;
|
||||
}
|
||||
} while (sub == -1);
|
||||
server.Accept(clients[sub]);
|
||||
clients[sub].used = true;
|
||||
players[sub].Initialize(ref clients[sub]);
|
||||
ParameterizedThreadStart start = new ParameterizedThreadStart(ReceiveThread);
|
||||
clientThreads[sub] = new Thread(start);
|
||||
clientThreads[sub].Start();
|
||||
}
|
||||
}
|
||||
} while (sub < 0);
|
||||
players[sub].client = server.Accept();
|
||||
players[sub].Initialize();
|
||||
//ParameterizedThreadStart start = new ParameterizedThreadStart(ReceiveThread);
|
||||
clientThreads[sub] = new Thread(ReceiveThread);
|
||||
clientThreads[sub].Start((object)sub);
|
||||
}
|
||||
}
|
||||
private void ReceiveThread(object obj)
|
||||
{
|
||||
int sub = (int)obj;
|
||||
while (stage == 2 && clients[sub].used)
|
||||
while (stage == 2 && players[sub].IsActive)
|
||||
{
|
||||
byte[] buf = new byte[256];
|
||||
clients[sub].Receive(buf);
|
||||
try
|
||||
{
|
||||
byte[] buf = new byte[255];
|
||||
int recved = players[sub].client.Receive(buf);
|
||||
if(recved > 0)
|
||||
players[sub].Receive(buf);
|
||||
}
|
||||
catch (Exception) // error receiving, close player
|
||||
{
|
||||
players[sub].Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Disconnect(int sub)
|
||||
{
|
||||
if (sub > 0 && sub < players./*Capacity*/Length)
|
||||
{
|
||||
clientThreads[sub].Abort();
|
||||
players[sub].Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private Thread serverThread;
|
||||
private ServerSocket server;
|
||||
private Socket server;
|
||||
private int stage;
|
||||
private int port;
|
||||
|
||||
List<BaseCharacter> players;
|
||||
//List<BaseCharacter> players;
|
||||
BaseCharacter[] players;
|
||||
|
||||
// TCP Stuff:
|
||||
private ClientSocket[] clients;
|
||||
private Thread[] clientThreads;
|
||||
private int numberOfClients;
|
||||
}
|
||||
}
|
|
@ -1,215 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
// TODO: ln 167 warning, catch more errors and don't return all of em as unknown :o
|
||||
|
||||
namespace MudEngine.Networking
|
||||
{
|
||||
class ServerSocket
|
||||
{
|
||||
public ServerSocket()
|
||||
{
|
||||
port = 0;
|
||||
stage = 0;
|
||||
type = 0;
|
||||
}
|
||||
|
||||
~ServerSocket()
|
||||
{
|
||||
port = 0;
|
||||
stage = 0;
|
||||
type = 0;
|
||||
}
|
||||
public int Initialize(int p,ProtocolType pt)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (stage == 0)
|
||||
{
|
||||
if (pt != ProtocolType.Tcp && pt != ProtocolType.Udp)
|
||||
return -3;
|
||||
port = p;
|
||||
type = pt;
|
||||
stage++;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int Start()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (stage == 1)
|
||||
{
|
||||
if (type == ProtocolType.Tcp)
|
||||
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, type);
|
||||
else
|
||||
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, type);
|
||||
stage++;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int Bind()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (stage == 2)
|
||||
{
|
||||
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
|
||||
sock.Bind(ipep);
|
||||
stage++;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int Listen()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (stage == 3 && type == ProtocolType.Udp)
|
||||
return -4;
|
||||
if (stage == 3)
|
||||
{
|
||||
sock.Listen(10);
|
||||
stage++;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int Accept(ClientSocket cs)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (type == ProtocolType.Udp)
|
||||
return -2;
|
||||
if (stage == 4)
|
||||
stage++;
|
||||
|
||||
if (stage == 5)
|
||||
{
|
||||
cs.sock = sock.Accept();
|
||||
cs.type = ProtocolType.Tcp;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int SendTo(byte[] ba, ClientSocket rcs)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (type != ProtocolType.Udp)
|
||||
return -3;
|
||||
|
||||
if (stage == 3)
|
||||
stage += 2;
|
||||
if (stage == 5)
|
||||
{
|
||||
IPEndPoint ipep = new IPEndPoint(rcs.ip, port);
|
||||
sock.SendTo(ba, ipep);
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int ReceiveFrom(byte[] ba, ClientSocket rcs)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (type != ProtocolType.Udp)
|
||||
return -3;
|
||||
|
||||
if (stage == 3)
|
||||
stage += 2;
|
||||
if (stage == 5)
|
||||
{
|
||||
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0);
|
||||
EndPoint ep = (EndPoint)ipep;
|
||||
sock.ReceiveFrom(ba, ref ep);
|
||||
|
||||
rcs.ip = ipep.Address;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public int CleanUp()
|
||||
{
|
||||
try
|
||||
{
|
||||
sock.Close();
|
||||
sock.Dispose();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public string GetError(int er_code)
|
||||
{
|
||||
if (er_code > 0)
|
||||
return "No Error";
|
||||
switch (er_code)
|
||||
{
|
||||
case -2:
|
||||
return "Method cannot be called yet.";
|
||||
case -3:
|
||||
return "ProtocolType not supported.";
|
||||
case -4:
|
||||
return "The ProtocolType does not support that method.";
|
||||
default:
|
||||
return "Unknown Error";
|
||||
}
|
||||
}
|
||||
|
||||
public int stage { get; private set; }
|
||||
public int port { get; private set; }
|
||||
public ProtocolType type { get; private set; }
|
||||
private Socket sock;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue