Bonsoir !
Je viens donc chercher un peu d'aide au niveau de la communication pour un emulateur 1.29.
Donc pour m'entrainer j'ai décidé de me lancer la dedans, j'en apprends pas mal d'ailleurs, mais je bloque souvent.. Actuellement ma partie Realm (oui j'ai fait un Realm & un Game, m'étant beaucoup inspiré d'Ancestra) fonctionne, dans le sens où j'arrive à me connecter jusqu'à la selection du serveur. A partir de la selection du serveur, c'est le "Game" qui doit prendre le relais, et c'est la que je bloque.
Donc lorsque mon client se connecte sur son jeu, mon Realm reçoit bien la connexion (port 444), mais ça on s'en fiche.
Lorsque je lance mon Game il faudrait que celui ci envoie un packet "CM" par exemple au Realm pour que celui ci sache que le serveur est ON. Le Realm ecoute donc sur le port 444 pour les clients et 436 pour les serveurs.
Mais je ne trouve pas le moyen pour que mon serveur envoie un packet sur l'adresse/Port du realm souhaité (jai bien vu le Socket.SendTo() mais ils me disent que le socket na pas encore été accepté). Enfin, c'est peut être très simple, je m'y prends peut être de la mauvaise façon, mais je galère un peu..
public class RealmServer
{
private Socket _clientSocket;
private Socket _gameServerSocket;
private TcpListener _clientListener;
private TcpListener _gameServerListener;
private Thread _clientThread;
private Thread _gameServerThread;
public RealmServer()
{
this._clientListener = new TcpListener(IPAddress.Parse(Configuration.REALM_ADDRESS), Configuration.REALM_PORT);
this._clientListener.Start();
this._clientThread = new Thread(new ThreadStart(WaitConnection));
this._clientThread.Start();
this._gameServerListener = new TcpListener(IPAddress.Parse(Configuration.REALM_ADDRESS), Configuration.GAME_PORT);
this._gameServerListener.Start();
this._gameServerThread = new Thread(new ThreadStart(WaitGameServerConnection));
this._gameServerThread.Start();
}
public void WaitGameServerConnection()
{
while (this._gameServerListener != null)
{
this._gameServerSocket = this._gameServerListener.AcceptSocket();
Logger.Infos("Demande de connexion reçue");
GameServerManager.LoadGameServer(_gameServerSocket, (((IPEndPoint)_gameServerSocket.RemoteEndPoint).Address).ToString());
}
}
public void WaitConnection()
{
while (this._clientListener != null)
{
this._clientSocket = this._clientListener.AcceptSocket();
new Client(this._clientSocket);
}
}
}
Voici la première instance "d'écoute" appelée.
Et là, GameServer (toujours dans le realm, c'est juste une classe) :
public class GameServer
{
private TcpListener _listener;
public Socket _gameServerSocket;
private delegate void DataReceivedFromClientEventHandler(byte[] Data);
private event DataReceivedFromClientEventHandler _dataReceivedFromGameServer;
private Thread _gameServerReceivingThread;
public int ID { get; set; }
public string IP { get; set; }
public int Port { get; set; }
public int GamePort { get; set; }
public int Population { get; set; }
public int MaxPlayers { get; set; }
public string Key { get; set; }
public int State { get; set; }
public int PlayersCount { get; set; }
public int ServerReqSubscribed { get; set; }
public GameServerManager DBManager { get; set; }
public bool GameConnected
{
get
{
return _gameServerSocket != null
&& _gameServerSocket.Connected
&& _gameServerSocket.Poll(2000, SelectMode.SelectRead)
&& _gameServerSocket.Available > 0;
}
}
public GameServer(Socket game, int id,string ip, int port, int maxplayers, string serverKey, GameServerManager serverManager, int serverReqSubscribed)
{
this._gameServerSocket = game;
this.ID = id;
this.IP = ip;
this.Port = port;
this.MaxPlayers = maxplayers;
this.Key = serverKey;
this.DBManager = serverManager;
this.ServerReqSubscribed = serverReqSubscribed;
this.PlayersCount = 0;
this.State = (int)Enums.ServerStateEnum.OFFLINE;
this.Population = (int)Enums.ServerPopulationEnum.RECOMMENDED;
this._dataReceivedFromGameServer += OnMessage;
this._listener = new TcpListener(IPAddress.Parse(this.IP), this.Port);
this._listener.Start();
this._gameServerReceivingThread = new System.Threading.Thread(Listen);
this._gameServerReceivingThread.Start();
}
public void Listen()
{
List<byte> ActualPacketBytes = new List<byte>();
while (GameConnected)
{
if (ActualPacketBytes.Count == 0)
{
if (_gameServerSocket.Available > 0)
{
byte[] buffer = new byte[_gameServerSocket.Available];
_gameServerSocket.Receive(buffer);
if (_dataReceivedFromGameServer != null)
_dataReceivedFromGameServer(buffer);
}
}
}
Logger.Infos("<< client disconnected");
}
private void OnMessage(byte[] Data)
{
Logger.Debug("Received packet from Game : " + Basic.GetStringOnReceived(Data));
}
public void Send(string packet)
{
if (GameConnected)
{
try
{
byte[] bytePacket = Basic.GetBytes(packet + "\x00");
this._gameServerSocket.Send(bytePacket);
Logger.Debug("Sent packet : " + Basic.GetString(bytePacket));
}
catch (Exception e)
{
Exceptions.ExceptionManager.OnException(e);
}
}
}
public override string ToString()
{
return this.ID + ";" + this.State + ";" + this.Population + ";" + this.ServerReqSubscribed;
}
}
Je n'ai pas encore trouvé de moyen d'envoyer un packet au lancement du serveur donc je n'ai pas de code à vous présenter du côté du Game...
Merci d'avance et désolé si j'ai ete confu dans mes explications,
Fygorn