/// <summary> /// BatlleServer connection Status Change event method /// Executed when status of connection to BattleServer is changed /// </summary> /// <param name="sender">EventDrivenTCPClient object</param> /// <param name="status">status of TCPClient</param> void BS_ConnectionStatusChanged(EventDrivenTCPClient sender, EventDrivenTCPClient.ConnectionStatus status) { if (status == EventDrivenTCPClient.ConnectionStatus.Connected) { Logger.Write("BattleServer.log", "BattleServer Connected"); BS.Send(Packet.ZoneConnectPacket()); Config.isBSConnected = true; Config.CONNECTED_SERVER_COUNT++; } else { if (Config.isBSConnected) { Logger.Write("BattleServer.log", "BattleServer Disonnected"); } Config.isBSConnected = false; } }
/// <summary> /// XX_ConnectionStatusChanged will check for connection status and set value true or false in Config variable accrodingly /// XX_DataReceived will process received data if required and send packets to client /// </summary> /// <summary> /// LoginServer connection Status Change event method /// Will be executed when connections status is changed /// </summary> /// <param name="sender">EventDrivenTCPClient object</param> /// <param name="status">status of TCPClient</param> void LS_ConnectionStatusChanged(EventDrivenTCPClient sender, EventDrivenTCPClient.ConnectionStatus status) { if (status == EventDrivenTCPClient.ConnectionStatus.Connected) { LS.Send(Packet.LoginServerConnectPacket()); Logger.Write("LoginServer.log", "LoginServer Connected"); Config.isLSConnected = true; LSReporter.Enabled = true; LSReporter.Start(); } else { if (Config.isLSConnected) { Logger.Write("LoginServer.log", "LoginServer Disconnected"); } LSReporter.Enabled = false; LSReporter.Stop(); Config.isLSConnected = false; } }
Button ShoutManually; //Button created run time /// <summary> /// Constructor /// Will create instance with specified ip and port /// Also will create 2 event methods /// 1)ConnectionStatusChanged when change in connection status /// 2)DataReceived when data is received /// </summary> public ZoneAgent(Main _Main) { //For LoginServer LS = new EventDrivenTCPClient(Config.LS_IP, Config.LS_PORT); LS.ConnectionStatusChanged += LS_ConnectionStatusChanged; LS.DataReceived += LS_DataReceived; //For AccountServer AS = new EventDrivenTCPClient(Config.AS_IP, Config.AS_PORT); AS.DataReceived += ZS_DataReceived; AS.ConnectionStatusChanged += AS_ConnectionStatusChanged; //For ZoneServer ZS = new EventDrivenTCPClient(Config.ZS_IP, Config.ZS_PORT); ZS.DataReceived += ZS_DataReceived; ZS.ConnectionStatusChanged += ZS_ConnectionStatusChanged; //For BattleServer BS = new EventDrivenTCPClient(Config.BS_IP, Config.BS_PORT); BS.DataReceived += ZS_DataReceived; BS.ConnectionStatusChanged += BS_ConnectionStatusChanged; clients = new List <Client>(); //initializing list of clients player = new Dictionary <int, PlayerInfo>(); //initializing dictionary of player information ZA = new TcpListener(Config.ZA_IP, Config.ZA_PORT); //initializing ZoneAgent Listener randomId = new Random(); //Timer to send report packet to LoginServer every 5 seconds LSReporter = new Timer { Interval = 5000 }; LSReporter.Tick += LSReporter_Tick; //Timer to display ping to each player PingDisplay = new Timer { Interval = 7000 }; PingDisplay.Tick += PingDisplay_Tick; PingDisplay.Enabled = true; PingDisplay.Start(); this._Main = _Main; // Taking refrence of main form //timer to send messages to client GMShout = new Timer(); GMShout.Tick += GMShout_Tick; //Button created runtime to send custom messages to client ShoutManually = new Button(); ShoutManually.Size = new System.Drawing.Size(243, 27); ShoutManually.Text = "Shout Manually"; ShoutManually.Location = new System.Drawing.Point(12, 325); ShoutManually.Click += ShoutManually_Click; _Main.Controls.Add(ShoutManually); //adding control i.e button on form //Connect to servers one by one try { LS.Connect(); AS.Connect(); ZS.Connect(); BS.Connect(); Start(); } catch (Exception connect) { Logger.Write(Logger.GetLoggerFileName("ZoneAgent"), "Connect : " + connect.ToString()); } }
/// <summary> /// ZoneServer Data Received methd /// Will be executed when data is received from ZoneServer /// Will split packet and add each packet in list and then send it to client /// </summary> /// <param name="sender">EventDrivenTCPClient object</param> /// <param name="data">byte[] data</param> void ZS_DataReceived(EventDrivenTCPClient sender, object data) { try { var packet = (byte[])Convert.ChangeType(data, typeof(byte[])); //File.WriteAllBytes("OGZS_" + Environment.TickCount + "_" + packet.Length, packet); Application.DoEvents(); var packetList = new List <byte[]>(); Application.DoEvents(); packetList.Clear(); Application.DoEvents(); Packet.SplitPackets(packet, packet.Length, ref packetList); foreach (var t in packetList) { var temp = new byte[4]; Array.Copy(t, 4, temp, 0, 4); var id = Packet.GetClientId(temp); if (player.ContainsKey(id)) { var playerinfo = player[id]; //Below condition is for disconneting client or reconnecting client if (playerinfo.ZoneStatus == Config.AS_ID) { if (t.Length == 952) { Write(playerinfo.Client.TcpClient, Packet.AlterAccountServerPacket(t)); } else { Write(playerinfo.Client.TcpClient, t); } } else { Write(playerinfo.Client.TcpClient, t); //Below condition is for disconneting client or reconnecting client if (t.Length == 12 && t[10] == 0x08 && t[11] == 0x11) { Config.PLAYER_COUNT--; //player count update _Main.Update_Player_Count(); //zonelog update _Main.Update_zonelog("<LC> UID = " + id + " " + playerinfo.Account + " User Left"); playerinfo.Prepared = false; LS.Send(Packet.SendDCToLS(id, playerinfo.Account, Packet.GetTime())); playerinfo.ZoneStatus = -1; ZS.Send(Packet.SendDCToASZS(id)); player.Remove(id); if (clients.Contains(playerinfo.Client)) { lock (clients) { clients.Remove(playerinfo.Client); } } } //Set Character Name else if (t.Length == 39 && t[10] == 0x06 && t[11] == 0x11) { playerinfo.CharName = Packet.GetCharName(Crypt.Decrypt(t), 12); } //Below condition is to reduce chance of other packets come under same conditions else if (t.Length > 18 && t[10] == 0x00 && t[11] == 0x18 && t[12] == 0x74 && t[13] == 0xCE && t[14] == 0xCA && t[15] == 0xE9 && t[16] == 0x87 && t[17] == 0x7F && t[18] == 0xAB) { var tempPacket = t; Packet.SetStatusValues(tempPacket); } } //Zone changed Packet : ZoneStatus Change if (t.Length == 11 && t[8] == 0x01 && t[9] == 0xE1) { //zonelog update _Main.Update_zonelog(playerinfo.Account + " (" + id + ") user zone changed " + playerinfo.ZoneStatus + " -> " + t[10]); playerinfo.ZoneStatus = t[10]; } } } } catch (Exception ZSDataArrival) { Logger.Write(Logger.GetLoggerFileName("ZoneServer"), "ZoneServer DataReceived : " + ZSDataArrival.ToString()); } }
/// <summary> /// LoginServer Data Received method /// Executed when data received from loginserver /// </summary> /// <param name="sender">EventDrivenTCPClient object</param> /// <param name="data">data received</param> void LS_DataReceived(EventDrivenTCPClient sender, object data) { try { var packet = (byte[])Convert.ChangeType(data, typeof(byte[])); switch (packet.Length) { case 40: //login var temp = new byte[4]; Array.Copy(packet, 4, temp, 0, 4); var clientid = Packet.GetClientId(temp); if (!player.ContainsKey(clientid)) { var accountid = Encoding.ASCII.GetString(packet).Substring(10, 15).Trim().TrimEnd('\0'); player.Add(clientid, new PlayerInfo(accountid, Packet.GetTime(), false, -1)); Config.PLAYER_COUNT++; if (Config.PLAYER_COUNT > Config.MAX_PLAYER_COUNT) { Config.MAX_PLAYER_COUNT = Config.PLAYER_COUNT; } //player count update _Main.Update_Player_Count(); //zonelog update _Main.Update_zonelog("<LC> UID = " + clientid.ToString() + " " + accountid + " Prepared"); } break; case 48: //duplicate login ; request DC to ZA from loginserver var tempByte = new byte[4]; Array.Copy(packet, 4, tempByte, 0, 4); var ClientID = Packet.GetClientId(tempByte); if (player.ContainsKey(ClientID)) { for (int i = clients.Count - 1; i >= 0; i--) { if (clients[i].UniqID == ClientID) { lock (clients) { clients[i].TcpClient.GetStream().Close(); clients.Remove(player[ClientID].Client); } break; } } Config.PLAYER_COUNT--; //player count update _Main.Update_Player_Count(); //zonelog update _Main.Update_zonelog("<LC> UID = " + ClientID.ToString() + " Dropped, Reason = Duplicate login"); LS.Send(Packet.DuplicateUserDCPacket(packet)); if (player[ClientID].ZoneStatus == Config.ZS_ID) { ZS.Send(Packet.SendDCToASZS(ClientID)); } else if (player[ClientID].ZoneStatus == Config.BS_ID) { BS.Send(Packet.SendDCToASZS(ClientID)); } player.Remove(ClientID); } break; default: //if any other packet received Logger.WriteBytes(Logger.GetLoggerFileName("LSNEW"), packet); break; } } catch (Exception LSDataArrival) { Logger.Write(Logger.GetLoggerFileName("LoginServer"), "LoginServer DataReceived : " + LSDataArrival.ToString()); } }