* Re-wrote the Server code again. Now much more reliable and passes all connections to the ConnectionManager properly.
* StandardCharacter re-wrote to support the new Server code. Also added event method support for various states. * ConnectionManager re-wrote to support the new server. * Work on Log message importance started * INetworked.Connect now requires a Socket as its parameter. * StandardGame no longer has Properties for MaxConnections and MaxQueuedConnections. This is handle via StandardGame.Start() parameters. * CommandLogin command added. Initial check-in and not fully implemented.
This commit is contained in:
parent
5b141c62ed
commit
27f7e31772
12 changed files with 314 additions and 163 deletions
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
namespace MudEngine.Core.Interfaces
|
namespace MudEngine.Core.Interfaces
|
||||||
{
|
{
|
||||||
|
@ -24,6 +25,6 @@ namespace MudEngine.Core.Interfaces
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Method for connecting a object to the server.
|
/// Method for connecting a object to the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Connect();
|
void Connect(Socket connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MudEngine.Core.Interfaces
|
||||||
/// <param name="path"></param>
|
/// <param name="path"></param>
|
||||||
Boolean Save(String filename);
|
Boolean Save(String filename);
|
||||||
|
|
||||||
Boolean Save(String filename, Boolean ignoreignoreFileWrite);
|
Boolean Save(String filename, Boolean ignoreFileWrite);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load method for retrieving saved data from file.
|
/// Load method for retrieving saved data from file.
|
||||||
|
|
|
@ -11,6 +11,16 @@ namespace MudEngine.Core
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Logger
|
public static class Logger
|
||||||
{
|
{
|
||||||
|
public enum Importance
|
||||||
|
{
|
||||||
|
Critical = 0,
|
||||||
|
Error = 1,
|
||||||
|
Warning = 2,
|
||||||
|
Information = 3,
|
||||||
|
Chat = 4,
|
||||||
|
All = 5
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Log Filename for the engine log.
|
/// The Log Filename for the engine log.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -42,6 +52,10 @@ namespace MudEngine.Core
|
||||||
_Messages.Clear();
|
_Messages.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void WriteLine(String message, Importance importance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a single line to the engine log file.
|
/// Writes a single line to the engine log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using MudEngine.GameScripts;
|
using MudEngine.GameScripts;
|
||||||
using MudEngine.Core.Interfaces;
|
using MudEngine.Core.Interfaces;
|
||||||
|
@ -25,6 +26,8 @@ namespace MudEngine.Game.Characters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StandardGame Game { get; private set; }
|
public StandardGame Game { get; private set; }
|
||||||
|
|
||||||
|
public string Filename { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets what this Characters role on the server is.
|
/// Gets what this Characters role on the server is.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -43,12 +46,15 @@ namespace MudEngine.Game.Characters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Boolean Immovable { get; set; }
|
public Boolean Immovable { get; set; }
|
||||||
|
|
||||||
|
public Boolean Enabled { get; set; }
|
||||||
|
|
||||||
//TODO: Add current location to characters
|
//TODO: Add current location to characters
|
||||||
//public IEnvironment CurrentLocation
|
//public IEnvironment CurrentLocation
|
||||||
|
|
||||||
protected CommandSystem Commands { get; private set; }
|
protected CommandSystem Commands { get; private set; }
|
||||||
|
|
||||||
public StandardCharacter(StandardGame game, String name, String description) : base(game, name, description)
|
public StandardCharacter(StandardGame game, String name, String description)
|
||||||
|
: base(game, name, description)
|
||||||
{
|
{
|
||||||
this.Game = game;
|
this.Game = game;
|
||||||
|
|
||||||
|
@ -59,7 +65,8 @@ namespace MudEngine.Game.Characters
|
||||||
this.OnConnectEvent += new OnConnectHandler(OnConnect);
|
this.OnConnectEvent += new OnConnectHandler(OnConnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StandardCharacter(StandardGame game, String name, String description, Socket connection) : this(game, name, description)
|
public StandardCharacter(StandardGame game, String name, String description, Socket connection)
|
||||||
|
: this(game, name, description)
|
||||||
{
|
{
|
||||||
this._Connection = connection;
|
this._Connection = connection;
|
||||||
|
|
||||||
|
@ -82,23 +89,93 @@ namespace MudEngine.Game.Characters
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void Load(string filename)
|
||||||
|
{
|
||||||
|
base.Load(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
this.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
internal void ExecuteCommand(string command)
|
internal void ExecuteCommand(string command)
|
||||||
{
|
{
|
||||||
//Process commands here.
|
if (this.Enabled)
|
||||||
if (this._InitialMessage)
|
|
||||||
{
|
{
|
||||||
command = this.CleanString(command);
|
Commands.Execute(command, this);
|
||||||
this._InitialMessage = false;
|
|
||||||
|
SendMessage("");
|
||||||
|
SendMessage("Command:", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Commands.Execute(command, this);
|
public void SendMessage(String data)
|
||||||
|
{
|
||||||
|
this.SendMessage(data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMessage(string message)
|
public void SendMessage(String data, Boolean newLine)
|
||||||
{
|
{
|
||||||
lock (this)
|
try
|
||||||
{
|
{
|
||||||
_Writer.WriteLine(message);
|
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
|
||||||
|
if (newLine)
|
||||||
|
data += "\n\r";
|
||||||
|
|
||||||
|
this._Connection.Send(encoding.GetBytes(data));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String GetInput()
|
||||||
|
{
|
||||||
|
string input = String.Empty;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] buf = new byte[1];
|
||||||
|
Int32 recved = this._Connection.Receive(buf);
|
||||||
|
|
||||||
|
if (recved > 0)
|
||||||
|
{
|
||||||
|
if (buf[0] == '\n' && buffer.Count > 0)
|
||||||
|
{
|
||||||
|
if (buffer[buffer.Count - 1] == '\r')
|
||||||
|
buffer.RemoveAt(buffer.Count - 1);
|
||||||
|
|
||||||
|
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
|
||||||
|
input = enc.GetString(buffer.ToArray());
|
||||||
|
buffer.Clear();
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
buffer.Add(buf[0]);
|
||||||
|
}
|
||||||
|
else if (recved == 0) //Disconnected
|
||||||
|
{
|
||||||
|
this.Enabled = false;
|
||||||
|
return "Disconnected.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
//Flag as disabled
|
||||||
|
this.Enabled = false;
|
||||||
|
return e.Message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,21 +185,16 @@ namespace MudEngine.Game.Characters
|
||||||
|
|
||||||
//Close our currently open socket.
|
//Close our currently open socket.
|
||||||
this._Connection.Close();
|
this._Connection.Close();
|
||||||
|
//this._LoopThread.Abort();
|
||||||
//Remove this character from the Connection Manager
|
//Remove this character from the Connection Manager
|
||||||
ConnectionManager.RemoveConnection(this);
|
//ConnectionManager.RemoveConnection(this, );
|
||||||
Console.WriteLine("Disconnect Complete.");
|
Console.WriteLine("Disconnect Complete.");
|
||||||
|
|
||||||
//Stop the Update() thread.
|
|
||||||
this._LoopThread.Abort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Connect()
|
public void Connect(Socket connection)
|
||||||
{
|
{
|
||||||
_LoopThread = new Thread(Update);
|
this._Connection = connection;
|
||||||
_LoopThread.Start();
|
|
||||||
|
|
||||||
this.SendMessage("");
|
|
||||||
OnConnectEvent();
|
OnConnectEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +205,9 @@ namespace MudEngine.Game.Characters
|
||||||
while (this.Game.Enabled)
|
while (this.Game.Enabled)
|
||||||
{
|
{
|
||||||
_Writer.Flush();
|
_Writer.Flush();
|
||||||
String line = _Reader.ReadLine();
|
//String line = CleanString(GetInput());
|
||||||
ExecuteCommand(line);
|
//Console.WriteLine(line);
|
||||||
|
//ExecuteCommand(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -146,8 +219,9 @@ namespace MudEngine.Game.Characters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String CleanString(string line)
|
String CleanString(String line)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if ((!String.IsNullOrEmpty(line)) && (line.Length > 0))
|
if ((!String.IsNullOrEmpty(line)) && (line.Length > 0))
|
||||||
{
|
{
|
||||||
System.Text.StringBuilder sb = new System.Text.StringBuilder(line.Length);
|
System.Text.StringBuilder sb = new System.Text.StringBuilder(line.Length);
|
||||||
|
@ -162,46 +236,43 @@ namespace MudEngine.Game.Characters
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return String.Empty;
|
return String.Empty;
|
||||||
|
* */
|
||||||
|
|
||||||
|
Regex invalidChars = new Regex(
|
||||||
|
@"(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\uFEFF\uFFFE\uFFFF]",
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(line))
|
||||||
|
return "";
|
||||||
|
else
|
||||||
|
return invalidChars.Replace(line, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void OnConnectHandler();
|
public delegate void OnConnectHandler();
|
||||||
public event OnConnectHandler OnConnectEvent;
|
public event OnConnectHandler OnConnectEvent;
|
||||||
public void OnConnect()
|
public void OnConnect()
|
||||||
{
|
{
|
||||||
_Writer.WriteLine(this.Game.Server.MOTD);
|
this.SendMessage(this.Game.Server.MOTD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void OnDisconnectHandler();
|
||||||
|
public event OnDisconnectHandler OnDisconnectEvent;
|
||||||
|
public void OnDisconnect()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void OnLoginHandler();
|
||||||
|
public event OnLoginHandler OnLoginEvent;
|
||||||
|
public void OnLogin()
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Socket _Connection;
|
private Socket _Connection;
|
||||||
private Thread _LoopThread;
|
|
||||||
private StreamReader _Reader;
|
private StreamReader _Reader;
|
||||||
private StreamWriter _Writer;
|
private StreamWriter _Writer;
|
||||||
private Boolean _InitialMessage;
|
private Boolean _InitialMessage;
|
||||||
|
private List<byte> buffer = new List<byte>();
|
||||||
public string Filename
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Load(string filename)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Destroy()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,6 @@ namespace MudEngine.Game
|
||||||
|
|
||||||
public Boolean Multiplayer { get; set; }
|
public Boolean Multiplayer { get; set; }
|
||||||
|
|
||||||
public Int32 MaximumPlayers { get; set; }
|
|
||||||
|
|
||||||
public Int32 MaxQueueSize { get; set; }
|
|
||||||
|
|
||||||
public Int32 MinimumPasswordSize { get; set; }
|
public Int32 MinimumPasswordSize { get; set; }
|
||||||
|
|
||||||
public Boolean AutoSave { get; set; }
|
public Boolean AutoSave { get; set; }
|
||||||
|
@ -49,18 +45,14 @@ namespace MudEngine.Game
|
||||||
this.Description = "A sample Mud game created using the Mud Designer kit.";
|
this.Description = "A sample Mud game created using the Mud Designer kit.";
|
||||||
this.Version = "1.0";
|
this.Version = "1.0";
|
||||||
this.Multiplayer = true;
|
this.Multiplayer = true;
|
||||||
this.MaximumPlayers = 50;
|
|
||||||
this.MinimumPasswordSize = 8;
|
this.MinimumPasswordSize = 8;
|
||||||
this.MaxQueueSize = 20;
|
|
||||||
this.AutoSave = true;
|
this.AutoSave = true;
|
||||||
|
|
||||||
//Setup our server.
|
//Setup our server.
|
||||||
this.Server = new Server(port);
|
this.Server = new Server(this, port);
|
||||||
|
|
||||||
this.Server.Port = port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean Start()
|
public Boolean Start(Int32 maxPlayers, Int32 maxQueueSize)
|
||||||
{
|
{
|
||||||
Logger.WriteLine("Starting up Standard Game");
|
Logger.WriteLine("Starting up Standard Game");
|
||||||
|
|
||||||
|
@ -74,7 +66,7 @@ namespace MudEngine.Game
|
||||||
//Load World
|
//Load World
|
||||||
|
|
||||||
//Start our server.
|
//Start our server.
|
||||||
this.Server.Start(this);
|
this.Server.Start(maxPlayers, maxQueueSize);
|
||||||
|
|
||||||
//If the server started without error, flag the Game as enabled.
|
//If the server started without error, flag the Game as enabled.
|
||||||
if (this.Server.Enabled)
|
if (this.Server.Enabled)
|
||||||
|
|
|
@ -59,20 +59,20 @@ namespace MudEngine.GameScripts
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Boolean Load(String filename)
|
public virtual void Load(String filename)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!File.Exists(filename))
|
if (!File.Exists(filename))
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
XElement data = XElement.Load(filename);
|
XElement data = XElement.Load(filename);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
42
MudEngine/WinPC_Engine/GameScripts/Commands/CommandLogin.cs
Normal file
42
MudEngine/WinPC_Engine/GameScripts/Commands/CommandLogin.cs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using MudEngine.Core.Interface;
|
||||||
|
using MudEngine.Game;
|
||||||
|
using MudEngine.Game.Characters;
|
||||||
|
using MudEngine.Game.Environment;
|
||||||
|
using MudEngine.GameScripts;
|
||||||
|
|
||||||
|
namespace MudEngine.GameScripts.Commands
|
||||||
|
{
|
||||||
|
public class CommandLogin : ICommand
|
||||||
|
{
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public List<string> Help { get; set; }
|
||||||
|
|
||||||
|
public CommandLogin()
|
||||||
|
{
|
||||||
|
Help = new List<string>();
|
||||||
|
Name = "Login";
|
||||||
|
Description = "Account login command.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(string command, Game.Characters.StandardCharacter character)
|
||||||
|
{
|
||||||
|
character.SendMessage("Please enter character name: ");
|
||||||
|
String name = String.Empty;
|
||||||
|
|
||||||
|
while (String.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
name = character.GetInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ namespace MudEngine.GameScripts.Commands
|
||||||
|
|
||||||
//Loop through each character on the server and broadcast the message.
|
//Loop through each character on the server and broadcast the message.
|
||||||
//TODO: This should only broadcast to characters that are in the same Environment.
|
//TODO: This should only broadcast to characters that are in the same Environment.
|
||||||
foreach (StandardCharacter c in ConnectionManager.Connections)
|
foreach (StandardCharacter c in character.Game.Server.ConnectionManager.GetConnectedCharacters())
|
||||||
{
|
{
|
||||||
//Only broadcast this message to those that are not the broadcastor.
|
//Only broadcast this message to those that are not the broadcastor.
|
||||||
if (c != character)
|
if (c != character)
|
||||||
|
|
|
@ -12,54 +12,94 @@ using MudEngine.Game.Characters;
|
||||||
|
|
||||||
namespace MudEngine.Networking
|
namespace MudEngine.Networking
|
||||||
{
|
{
|
||||||
public static class ConnectionManager
|
public class ConnectionManager
|
||||||
{
|
{
|
||||||
//Collection of currently connected players.
|
//Collection of currently connected players.
|
||||||
public static List<StandardCharacter> Connections { get; set; }
|
internal List<Thread> _ConnectedThreads;
|
||||||
|
internal List<StandardCharacter> _ConnectedCharacters;
|
||||||
|
|
||||||
|
public ConnectionManager(Int32 maxPlayers)
|
||||||
|
{
|
||||||
|
this._ConnectedCharacters = new List<StandardCharacter>(maxPlayers);
|
||||||
|
this._ConnectedThreads = new List<Thread>(maxPlayers);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new character for the player and sets it up on the server.
|
/// Creates a new character for the player and sets it up on the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="game"></param>
|
/// <param name="game"></param>
|
||||||
/// <param name="connection"></param>
|
/// <param name="connection"></param>
|
||||||
public static void AddConnection(StandardGame game, Socket connection)
|
public void AddConnection(StandardGame game, Socket connection)
|
||||||
{
|
{
|
||||||
//Exception checking.
|
|
||||||
if (Connections == null)
|
|
||||||
Connections = new List<StandardCharacter>();
|
|
||||||
|
|
||||||
//Instance a new character and provide it with the Socket.
|
//Instance a new character and provide it with the Socket.
|
||||||
StandardCharacter character = new StandardCharacter(game, "New Player", "New networked client.", connection);
|
StandardCharacter character = new StandardCharacter(game, "New Player", "New networked client.", connection);
|
||||||
|
|
||||||
//Add it to the Connections collection
|
|
||||||
Connections.Add(character);
|
|
||||||
|
|
||||||
//Invoke the Characters Server connection method
|
//Invoke the Characters Server connection method
|
||||||
character.Connect();
|
character.Connect(connection);
|
||||||
|
this._ConnectedCharacters.Add(character);
|
||||||
|
this._ConnectedThreads.Add(new Thread(ReceiveDataThread));
|
||||||
|
|
||||||
|
Int32 index = this._ConnectedThreads.Count - 1;
|
||||||
|
this._ConnectedThreads[index].Start(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardCharacter[] GetConnectedCharacters()
|
||||||
|
{
|
||||||
|
return this._ConnectedCharacters.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReceiveDataThread(Object index)
|
||||||
|
{
|
||||||
|
StandardCharacter character = this._ConnectedCharacters[(Int32)index];
|
||||||
|
character.Initialize();
|
||||||
|
|
||||||
|
while (character.Game.Server.Status == ServerStatus.Running &&
|
||||||
|
character.Enabled)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
character.ExecuteCommand(character.GetInput());
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
RemoveConnection(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveConnection(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the specified player character from the server.
|
/// Removes the specified player character from the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="character"></param>
|
/// <param name="character"></param>
|
||||||
public static void RemoveConnection(StandardCharacter character)
|
public void RemoveConnection(StandardCharacter character)
|
||||||
{
|
{
|
||||||
Connections.Remove(character);
|
character.Disconnect();
|
||||||
|
foreach (StandardCharacter c in this._ConnectedCharacters)
|
||||||
|
{
|
||||||
|
if (c.ID == character.ID)
|
||||||
|
{
|
||||||
|
Int32 index = _ConnectedCharacters.IndexOf(c);
|
||||||
|
this._ConnectedCharacters.Remove(character);
|
||||||
|
this._ConnectedThreads[index].Abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disconnects all of the currently connected clients.
|
/// Disconnects all of the currently connected clients.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void DisconnectAll()
|
public void DisconnectAll()
|
||||||
{
|
{
|
||||||
if (Connections == null)
|
for (Int32 i = 0; i < this._ConnectedCharacters.Count; i++)
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (StandardCharacter character in Connections)
|
|
||||||
{
|
{
|
||||||
character.Disconnect();
|
this._ConnectedCharacters[i].Disconnect();
|
||||||
|
this._ConnectedThreads[i].Abort();
|
||||||
}
|
}
|
||||||
Connections.Clear();
|
|
||||||
|
this._ConnectedCharacters.Clear();
|
||||||
|
this._ConnectedThreads.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,103 +14,83 @@ using MudEngine.Game.Characters;
|
||||||
|
|
||||||
namespace MudEngine.Networking
|
namespace MudEngine.Networking
|
||||||
{
|
{
|
||||||
|
public enum ServerStatus
|
||||||
|
{
|
||||||
|
Stopped = 0,
|
||||||
|
Starting = 1,
|
||||||
|
Running = 2,
|
||||||
|
}
|
||||||
|
|
||||||
[Category("Networking")]
|
[Category("Networking")]
|
||||||
public class Server
|
public class Server
|
||||||
{
|
{
|
||||||
[Category("Networking")]
|
public ServerStatus Status { get; private set; }
|
||||||
[Description("The name of this server")]
|
|
||||||
public String Name { get; set; }
|
|
||||||
|
|
||||||
[Category("Networking")]
|
public Int32 Port { get; private set; }
|
||||||
public Int32 Port { get; set; }
|
|
||||||
|
|
||||||
[Category("Networking")]
|
public Int32 MaxConnections { get; private set; }
|
||||||
[Description("The Message Of The Day that is presented to users when they connect.")]
|
|
||||||
public String MOTD { get; set; }
|
|
||||||
|
|
||||||
[Category("Networking")]
|
public Int32 MaxQueuedConnections { get; private set; }
|
||||||
[Description("Maximum number of people that can connect and play on this server at any time.")]
|
|
||||||
public Int32 MaxConnections { get; set; }
|
|
||||||
|
|
||||||
[Category("Networking")]
|
public ConnectionManager ConnectionManager { get; private set; }
|
||||||
[Description("Maximum number of poeple that can be queued for connection.")]
|
|
||||||
public Int32 QueuedConnectionLimit { get; set; }
|
|
||||||
|
|
||||||
[Browsable(false)]
|
|
||||||
public Boolean Enabled { get; private set; }
|
public Boolean Enabled { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
public String MOTD { get; set; }
|
||||||
/// Sets up a server on the specified port.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="port"></param>
|
|
||||||
/// <param name="maxConnections"></param>
|
|
||||||
public Server(Int32 port)
|
|
||||||
{
|
|
||||||
Logger.WriteLine("Initializing Mud Server Settings");
|
|
||||||
this.Port = port;
|
|
||||||
this.MaxConnections = 50;
|
|
||||||
this.QueuedConnectionLimit = 20;
|
|
||||||
this.Name = "New Server";
|
|
||||||
this.MOTD = "Welcome to a sample Mud Engine game server!";
|
|
||||||
|
|
||||||
|
public Server(StandardGame game, Int32 port)
|
||||||
|
{
|
||||||
|
this.Port = port;
|
||||||
|
this.Status = ServerStatus.Stopped;
|
||||||
|
this.MaxConnections = 100;
|
||||||
|
this.MaxQueuedConnections = 10;
|
||||||
|
|
||||||
|
this._Game = game;
|
||||||
this._Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
this._Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
this._Server.Bind(new IPEndPoint(IPAddress.Any, this.Port));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void Start(Int32 maxConnections, Int32 maxQueueSize)
|
||||||
/// Starts the game server. It will listen on a different thread of incoming connections
|
|
||||||
/// </summary>
|
|
||||||
public void Start(StandardGame game)
|
|
||||||
{
|
{
|
||||||
//Start the server.
|
if (this.Status != ServerStatus.Stopped)
|
||||||
Logger.WriteLine("Starting Mud Server.");
|
return;
|
||||||
|
|
||||||
//Start listening for connections
|
this.Status = ServerStatus.Starting;
|
||||||
this._Server.Listen(this.QueuedConnectionLimit);
|
|
||||||
|
|
||||||
//Launch the new connections listener on a new thread.
|
this.MaxConnections = maxConnections;
|
||||||
this._ConnectionPool = new Thread(AcceptConnection);
|
this.ConnectionManager = new ConnectionManager(this.MaxConnections);
|
||||||
this._ConnectionPool.Start();
|
|
||||||
|
|
||||||
//Flag the server as enabled.
|
try
|
||||||
|
{
|
||||||
|
IPEndPoint ip = new IPEndPoint(IPAddress.Any, this.Port);
|
||||||
|
this._Server.Bind(ip);
|
||||||
|
this._Server.Listen(this.MaxQueuedConnections);
|
||||||
|
|
||||||
|
this.Status = ServerStatus.Running;
|
||||||
this.Enabled = true;
|
this.Enabled = true;
|
||||||
|
|
||||||
//Save a reference to the currently active game
|
this._ServerThread = new Thread(ServerLoop);
|
||||||
this._Game = game;
|
this._ServerThread.Start();
|
||||||
|
}
|
||||||
Logger.WriteLine("Server started.");
|
catch
|
||||||
|
{
|
||||||
|
this.Status = ServerStatus.Stopped;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
//Flag the server as disabled.
|
|
||||||
this.Enabled = false;
|
|
||||||
|
|
||||||
//Stop the thread from listening for accepting new conections
|
|
||||||
this._ConnectionPool.Abort();
|
|
||||||
|
|
||||||
//Disconnect all of the currently connected clients.
|
|
||||||
ConnectionManager.DisconnectAll();
|
|
||||||
|
|
||||||
//Stop the server.
|
|
||||||
this._Server.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AcceptConnection()
|
private void ServerLoop()
|
||||||
{
|
{
|
||||||
//While the server is enabled, constantly check for new connections.
|
while (this.Status == ServerStatus.Running)
|
||||||
while (this.Enabled)
|
|
||||||
{
|
{
|
||||||
//Grab the new connection.
|
this.ConnectionManager.AddConnection(this._Game, this._Server.Accept());
|
||||||
Socket incomingConnection = this._Server.Accept();
|
|
||||||
|
|
||||||
//Send it to the Connection Manager so a Character can be instanced.
|
|
||||||
ConnectionManager.AddConnection(this._Game, incomingConnection);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Socket _Server;
|
|
||||||
private Thread _ConnectionPool;
|
|
||||||
private StandardGame _Game;
|
private StandardGame _Game;
|
||||||
|
private Socket _Server;
|
||||||
|
private Thread _ServerThread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
<Compile Include="Core\ObjectCollection.cs" />
|
<Compile Include="Core\ObjectCollection.cs" />
|
||||||
<Compile Include="DAL\DataPaths.cs" />
|
<Compile Include="DAL\DataPaths.cs" />
|
||||||
<Compile Include="DAL\XMLData.cs" />
|
<Compile Include="DAL\XMLData.cs" />
|
||||||
|
<Compile Include="GameScripts\Commands\CommandLogin.cs" />
|
||||||
<Compile Include="GameScripts\Commands\CommandSay.cs" />
|
<Compile Include="GameScripts\Commands\CommandSay.cs" />
|
||||||
<Compile Include="Game\Characters\CharacterRoles.cs" />
|
<Compile Include="Game\Characters\CharacterRoles.cs" />
|
||||||
<Compile Include="Game\Characters\CharacterStats.cs" />
|
<Compile Include="Game\Characters\CharacterStats.cs" />
|
||||||
|
|
|
@ -23,9 +23,19 @@ namespace WinPC_Server
|
||||||
Logger.Enabled = true;
|
Logger.Enabled = true;
|
||||||
Logger.ConsoleOutPut = true;
|
Logger.ConsoleOutPut = true;
|
||||||
|
|
||||||
//Instance and start the game. This will start the server.
|
//Instance and setup our game
|
||||||
StandardGame game = new StandardGame("Sample Game");
|
StandardGame game = new StandardGame("Sample Game");
|
||||||
game.Start();
|
game.AutoSave = true;
|
||||||
|
game.Debugging = true;
|
||||||
|
game.Description = "This is a very simple game that was created to demonstrate MUD game creation with the Mud Designer Game Engine.";
|
||||||
|
game.HiddenRoomNames = false;
|
||||||
|
game.Multiplayer = true;
|
||||||
|
game.Server.MOTD = "Welcome to the Sample Game desmontratio server!";
|
||||||
|
game.Version = "1.0";
|
||||||
|
game.Website = "http://muddesigner.codeplex.com";
|
||||||
|
|
||||||
|
//Start the game and server.
|
||||||
|
game.Start(100, 20);
|
||||||
|
|
||||||
//Setup our Server console input class
|
//Setup our Server console input class
|
||||||
ConsoleInput input = new ConsoleInput();
|
ConsoleInput input = new ConsoleInput();
|
||||||
|
@ -38,7 +48,7 @@ namespace WinPC_Server
|
||||||
while (game.Enabled)
|
while (game.Enabled)
|
||||||
{
|
{
|
||||||
//Check the queued Console Input
|
//Check the queued Console Input
|
||||||
if (input.Message.Equals("exit"))
|
if (input.Message.ToLower().Equals("exit"))
|
||||||
{
|
{
|
||||||
//If the server console has a exit command entered.
|
//If the server console has a exit command entered.
|
||||||
//stop the game. This will set game.Enabled to false.
|
//stop the game. This will set game.Enabled to false.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue