///
// Method used to open the server connection (when player is host)
///
private void btn_Go_Click(object sender, System.EventArgs e)
{
//start the server
OvServer.StartConnection();
//start the client
//if the player is hosting, server and client are on the same machine
//so we can use localhost as url
OvClient.TryConnection(portNo, "localhost");
// subscribe to the event which is fired when a new client connects
Overlapped.ClientConnected += new EmptyDelegate(OnClientConnected);
// host always has the Player-ID 1
mMainForm.PlayerInstance.PlayerID = 1;
// tell the server that a client connected (host instance itself connects)
OvClient.Server.ClientConnected(mMainForm.PlayerInstance);
// Init refresh timer to check for updates
mRefreshTimer.AutoReset = true;
mRefreshTimer.Start();
mRefreshTimer.Elapsed += new System.Timers.ElapsedEventHandler(mRefreshTimer_Elapsed);
// subsribe to the event that is triggered if any of the clients changed
// its team selection
OvClient.Server.ConnectionStatusChanged +=new EmptyDelegate(Server_ConnectionStatusChanged);
// subscribe to the event that is triggered if any of the clients changed
// its ready-state
OvClient.Server.ReadyStateChanged += new EmptyDelegate(Server_ReadyStateChanged);
// show the host user that connection has been opened
this.lbl_ConnectionStatus.Text = "Waiting for Players";
this.lbl_ConnectionStatus.BackColor = Color.YellowGreen;
}
using System;
using System.Collections;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using Overlapped.IniFile;
namespace Overlapped.Server
{
/// <summary>
/// The game server, singleton class
/// </summary>
public class OvServer
{
private static int mPortNo;
private OvIniHandler mIniFile;
private static OvServer mInstance = new OvServer();
private OvServer()
{
mIniFile = new OvIniHandler(Application.StartupPath + @"\ServerSettings.ini");
mPortNo = mIniFile.GetInt("Connection", "ServerPort", 8050);
}
// Starting the server connection / enabling the remote object
public static void StartConnection()
{
// create my own sinks because type filter level has to be set to full
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
// Set TypeFilterLevel to full (needed so send remote events)
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
// Initialize the server channel
IDictionary props = new Hashtable();
props["port"] = mPortNo;
props["typeFilterLevel"] = TypeFilterLevel.Full;
HttpChannel chan = new HttpChannel(props,clientProvider,serverProvider);
// Register server channel
ChannelServices.RegisterChannel(chan);
//enable remote object
RemotingConfiguration.RegisterWellKnownServiceType(typeof(OvRemoteObject),"Overlapped",WellKnownObjectMode.Singleton);
}
// get singleton-instance
public static OvServer GetInstance()
{
return mInstance;
}
}
}
using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
using Overlapped.Server;
namespace Overlapped.Client
{
/// <summary>
/// Client Class
/// </summary>
public class OvClient
{
/// <summary>
/// Singleton instance of this client
/// </summary>
private static OvClient mInstance = new OvClient();
private static OvRemoteObject mServer;
private OvClient()
{
mServer = null;
}
public static OvClient GetInstance()
{
return mInstance;
}
//Connect to the server
public static void TryConnection(int port, string url)
{
BinaryClientFormatterSinkProvider clientProvider = new inaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
//init client channel
IDictionary props = new Hashtable();
props["port"] = 0;
//create unique client name
string s = System.Guid.NewGuid().ToString();
props["name"] = s;
props["typeFilterLevel"] = TypeFilterLevel.Full;
HttpChannel chan = new HttpChannel(props,clientProvider,serverProvider);
ChannelServices.RegisterChannel(chan);
Type typeofRO = typeof(OvRemoteObject);
//Activate RemoteObject
mServer = (OvRemoteObject)Activator.GetObject(typeofRO, "http://"+url+":"+port+"/Overlapped");
}
public static OvRemoteObject Server
{
get {return mServer;}
}
public static Hashtable GetPlayerConnections()
{
return mServer.GetPlayerSelections();
}
}
}
using System;
using System.Collections;
using System.Windows.Forms;
using System.Runtime.Remoting;
using Overlapped.TypeDefs;
using Overlapped.Core;
namespace Overlapped.Server
{
[Serializable]
public class OvRemoteObject : MarshalByRefObject
{
private Hashtable mPlayerConnectionStatus;
private OvGameState mGameState;
public OvRemoteObject()
{
mPlayerConnectionStatus = new Hashtable();
mGameState = new OvGameState();
}
public static event InitDelegate NewClient;
public event EmptyDelegate ConnectionStatusChanged;
public event EmptyDelegate ReadyStateChanged;
// a new client connected to the server
public int ClientConnected(OvPlayer playerInstance)
{
// assign player-ID to the new player instance
playerInstance.PlayerID = mPlayerConnectionStatus.Count + 1;
// save player instance
mPlayerConnectionStatus.Add(playerInstance.PlayerID, playerInstance);
// notify all other clients that a new client connected
// (exclude server, because it has been notified already)
if(playerInstance.PlayerName
!=((OvPlayer)mPlayerConnectionStatus[1]).PlayerName)
*** // use method in the client instance for notification (only works in LAN)
*** playerInstance.NewClient(playerInstance);
*** // use event to notify clients (only works in LAN)
*** //NewClient(playerInstance);
*** // set new connection status in all clients (only works in LAN)
*** if(ConnectionStatusChanged != null)
*** ConnectionStatusChanged();
// return last Player-ID
return mPlayerConnectionStatus.Count;
}
//works
public Hashtable GetPlayerConnectionStatus()
{
return (Hashtable)(mPlayerConnectionStatus.Clone());
}
//works
public Hashtable GetPlayerSelections()
{
return mPlayerConnectionStatus;
}
public OvGameState GameState
{
get { return mGameState; }
set { mGameState = value; }
}
// Notify clients if connection state changed
public void UpdateConnectionStatus(int playerNo, string playerSelection)
{
((OvPlayer)mPlayerConnectionStatus[playerNo]).Team = playerSelection;
*** if(ConnectionStatusChanged != null)
*** ConnectionStatusChanged(); // Only works via LAN
}
// Notify clients if ready-state changed
public void UpdateReadyStatus(int playerNo, bool readyState)
{
((OvPlayer)mPlayerConnectionStatus[playerNo]).ReadyState = readyState;
*** if(ReadyStateChanged != null)
*** ReadyStateChanged(); // Only works via LAN
}
public Hashtable PlayerConnectionStatus
{
get { return mPlayerConnectionStatus; }
set { mPlayerConnectionStatus = value; }
}
public void AddPlayerToGameState(int pID, OvPlayer player)
{
GameState.AddPlayer(pID, player);
}
// ... (cut off the rest)
// ...
}
}