public static void Remove(Dictionary <ulong, ClientHandler> clients, SyncReceiver syncServer, EventHandler events, ulong magic, ClientHandler client, System.Net.EndPoint ip, int AccID) { try { foreach (ClientHandler cli in clients.Values) { if (cli.RemoteEndPoint == null) { clients.Remove((ulong)cli.Metadata["magic"]); Authentication.GetUser(syncServer, (ulong)cli.Metadata["magic"]); client.Disconnect(); } else if (cli.RemoteEndPoint == ip) { clients.Remove(magic); Authentication.GetUser(syncServer, magic); events.ClientDisconnected(events, client); } } } catch (Exception) { Log.Notice("Account {0} already removed", AccID); } }
public static void SubPasswordDelRequest(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { packet.Skip(4); var pass = packet.ReadString(10).Trim('\0'); var syncServer = client.Metadata["syncServer"] as SyncReceiver; var checksub = SubpassManagement.CheckSubPw(syncServer, client.AccountID, pass); var tries = 0; builder.New(0x410); { if (checksub) { client.Metadata["subTries"] = 0; builder += 1; // success builder += (byte)0x00; // failed times } else { client.Metadata["subTries"] = (int)client.Metadata["subTries"] + 1; tries = (int)client.Metadata["subTries"]; builder += 0; // failed builder += (byte)tries; // failed times } builder += 1; } client.Send(builder, "SubPasswordDelRequest"); if ((int)client.Metadata["subTries"] > 3) { client.Disconnect(); } }
public static void CharacterDeleteCheckSubPassword(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { var subpw = packet.ReadString(10).Trim('\0'); var syncServer = client.Metadata["syncServer"] as SyncReceiver; var verify = SubpassManagement.CheckSubPw(syncServer, client.AccountID, subpw); var tries = 0; builder.New(0x870); { if (verify) { client.Metadata["subTries"] = 0; builder += 1; // success builder += (byte)0; // failed times } else { client.Metadata["subTries"] = (int)client.Metadata["subTries"] + 1; tries = (int)client.Metadata["subTries"]; builder += 0; // failed builder += (byte)tries; // failed times } } client.Send(builder, "CharacterDeleteCheckSubPassword"); if ((int)client.Metadata["subTries"] > 3) { client.Disconnect(); } }
public static void SayInShout(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { //byte[] b; var name = client.Metadata["name"] as string; int size = packet.ReadByte() - 5; packet.Skip(2); var type = packet.ReadByte(); var x = packet.ReadByte(); var y = packet.ReadByte(); var msg = packet.ReadString(size); if (msg == ".quit") { client.Disconnect(); return; } var id = (uint)client.Metadata["cid"]; var clients = client.Metadata["clients"] as Dictionary <ulong, ClientHandler>; foreach (var c in clients.Values) { builder.New(0x18A); { builder += (int)id; builder += (byte)name.Length; builder += (byte)(msg.Length + 6); builder += name; builder += (byte)0xFE; builder += (byte)0xFE; builder += type; builder += x; builder += y; builder += msg; builder += (byte)0; //b = builder.Data; } c.Send(builder, "LoudMsgChannel"); } events.SaidChannel("world.700.LoudMsgChannel", (int)id, name, msg); }
public static void AddSkillPoints(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { var sync = client.Metadata["syncServer"] as SyncReceiver; var server = (int)client.Metadata["server"]; Character character = client.Metadata["fullchar"] as Character; var skill = packet.ReadUShort(); var slot = packet.ReadByte(); var oldlevel = packet.ReadUShort(); var newlevel = packet.ReadUShort(); if ((newlevel == oldlevel + 1) || (newlevel == oldlevel - 1)) { CharacterManagement.UpdateSkillPoints(sync, server, character.id, skill, newlevel, slot); builder.New(0x0A56); client.Send(builder, "AddSkillPoints"); } else //Punishment for hackers :D { var map = client.Metadata["map"] as IMap; CharacterManagement.UpdatePosition(sync, server, client.AccountID, character.slot, character.map, character.x, character.y); client.Disconnect(); } }
public static void MessageEvent(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { Character character = client.Metadata["fullchar"] as Character; var name = character.name; var x = (ushort)character.x; var y = (ushort)character.y; var id = character.id; var map = client.Metadata["map"] as IMap; var clients = map.GetSurroundingClients(client, 1); int unk = packet.ReadInt(); packet.Skip(4); int size = packet.ReadShort() - 3; packet.Skip(2); var type = packet.ReadByte(); var msg = packet.ReadString(size); var smsg = msg.Split(' '); if (msg == "/quit") { client.Disconnect(); return; } #region DebugCommands #if DEBUG if (smsg.Length > 1 && string.IsNullOrEmpty(smsg[0]) == false) { switch (smsg[0]) { case "_drop": int itemid = 0; if (int.TryParse(smsg[1], out itemid)) { map.DropItem(x, y, itemid, (uint)id, (uint)id); } break; case "_warp": ushort mapid = 0; ushort curx = 0; ushort cury = 0; if (!ushort.TryParse(smsg[1], out mapid)) { return; } if (!ushort.TryParse(smsg[2], out curx)) { return; } if (!ushort.TryParse(smsg[3], out cury)) { return; } var p = client.CreatePacket("PC_WarpCommand", mapid, curx, cury, client); events.Warped("world.Initialized", client, mapid, curx, cury); client.Send(p, "PC_WarpCommand"); break; case "_levelup": ushort level = 0; if (!ushort.TryParse(smsg[1], out level)) { return; } builder.New(0x03F0); { builder += (byte)2; builder += (uint)1371; builder += (uint)1367; } client.Send(builder, "LevelUp"); break; case "_spawn": ushort mobid = 0; ushort specid = 0; if (!ushort.TryParse(smsg[1], out mobid)) { return; } if (!ushort.TryParse(smsg[2], out specid)) { return; } var p1 = client.CreatePacket("MobSpawned", mobid, specid); client.Send(p1, "MobSpawned"); break; case "/Partytime": uint pid = 1337; foreach (var c in clients) { builder.New(0xC9); { builder += (int)pid; builder += (byte)12; //b = builder.Data; } var timestamp = (uint)c.Metadata["timestamp"]; var style = (uint)c.Metadata["style"]; c.Send(builder, "NFY_DelUserList"); builder.New(0xC8); { builder += (short)0x3101; builder += (int)pid++; builder += (short)0x000D; builder += (short)0x0100; builder += 1; builder += Environment.TickCount - (int)timestamp; builder += (short)(x + 1); builder += (short)y; builder += (short)(x + 1); builder += (short)y; builder += (byte)0; builder += 0; builder += (short)0; builder += (int)style; builder += (byte)1; builder += (byte)0; builder += 0; builder += 0; builder += (byte)0; var equipment = (List <CItem>)c.Metadata["equipment"]; builder += (byte)(equipment.Count); builder += (short)0; builder += (byte)0; builder += 0; name = "PARTY TIME!!"; builder += (byte)(name.Length + 1); builder += name; builder += (byte)0; foreach (var e in equipment) { builder += (short)e.ID; builder += e.Slot; } } c.Send(builder, "NFY_NewUserList"); } return; } } #endif #endregion builder.New(0xD9); { builder += id; builder += (byte)0; builder += (byte)unk; builder += (byte)0; builder += (byte)(msg.Length + 3); builder += (byte)0; builder += (byte)254; builder += (byte)254; builder += type; builder += msg; builder += new byte[3]; } foreach (var c in clients) { c.Send(builder, "NFY_MessageEvnt"); } events.SaidLocal("world.MessageEvnt", id, name, msg); }
/* * Unknown_7D6 Packet * ------------------------- * Client2Server Structure: * * ushort : magic code * ushort : size * int : padding * ushort : opcode * * int : unk1 * byte[] : encrypted data #array size depends on RSA keylength, see PublicKey packet * ------------------------- * Server2Client Structure: * * ushort : magic code * ushort : size * ushort : opcode * * int : unk1 #is set to 1 upon successful login; otherwise 0 * int : unk2 * byte : unk3 * int : status #account status * ------------------------- * If login was successful, server sends another Unknown_7D6 packet: * Server2Client Structure: * * ushort : magic code * ushort : size * ushort : opcode * * int : unk1 #is set to 1 upon successful login; otherwise 0 * int : unk2 * byte : unk3 * int : status #account status * int : unk4 * byte : unk5 * int : unk6 * long : unk7 * byte : unk8 * int : unk9 * byte : unk10 * int : unk11 * int : unk12 * int : unk13 * char[32] : auth key #possibly used for cash shop * short : unk14 * byte : server count * * foreach server * byte : server id * byte : character count * * byte[] : unk15 #array length is 248 */ #endregion public static void Unknown_7D6(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { packet.Skip(4); var rsa = client.Metadata["rsa"] as RSA; if (rsa == null) { Log.Error("Unable to decrypt RSA data!"); client.Disconnect(); client = null; return; } byte[] encrypted = packet.ReadBytes(rsa.KeyLength / 8); // keylength is in bits byte[] details = rsa.Decrypt(encrypted); byte[] tmpdata = new byte[16]; if (details == null) { Log.Error("Unable to decrypt RSA data!"); client.Disconnect(); client = null; return; } Array.Copy(details, tmpdata, 16); string name = Encoding.UTF8.GetString(tmpdata).Trim('\0'); Array.Copy(details, 65, tmpdata, 0, 16); string pass = Encoding.UTF8.GetString(tmpdata).Trim('\0'); Log.Notice("Login authentication: " + name); string ip = client.RemoteEndPoint.ToString().Split(':')[0]; var syncServer = client.Metadata["syncServer"] as SyncReceiver; var data = Authentication.FetchAccount(syncServer, name, pass); bool kick = false; if (data == null || data.id == -1) { builder.New(0x7D6); { builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.OutOfService; } events.FailedLogin("login.AuthAccount", new LoginEventArgs(name, pass, ip, LoginResult.OutOfService)); client.Send(builder, "Unknown_7D6"); return; } builder.New(0x7D6); { switch (data.status) { case AuthStatus.Unverified: builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Unverified; break; case AuthStatus.Banned: builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Banned; break; case AuthStatus.IncorrectName: case AuthStatus.IncorrectPass: builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Incorrect; var tmp = data.status == AuthStatus.IncorrectName ? LoginResult.UnknownUsername : LoginResult.WrongPassword; events.FailedLogin("login.AuthAccount", new LoginEventArgs(name, pass, ip, tmp)); break; case AuthStatus.Verified: client.AccountID = data.id; Authentication.UpdateIPDate(syncServer, client.AccountID, ip, DateTime.Now); Authentication.UpdateOnline(syncServer, client.AccountID, true); builder += 1; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Normal; events.SuccessfulLogin("login.AuthAccount", new LoginEventArgs(name, pass, ip, LoginResult.Success, client.AccountID)); break; default: kick = true; break; } } client.Send(builder, "Unknown_7D6"); if (kick) { client.Disconnect(); } if (data.id > 0 && data.status == AuthStatus.Verified) { builder.New(0x7D6); { builder += 1; builder += 0x0900; builder += (byte)0; builder += (int)AccountStatus.Normal; builder += 0x4B6359; builder += (byte)1; builder += 0x67; builder += (long)0; builder += (byte)0; builder += 0x43A56B60; builder += (byte)0; builder += 1; builder += 0; builder += 0; builder += "0A47130EA1D04A4D99D58F094B7E88C3"; // AuthKey builder += (short)0; builder += (byte)1; // Char Num of all servers builder += (byte)1; // Server ID builder += (byte)1; // CharNum } client.Send(builder, "Unknown_7D6"); URLToClient(packet, builder, client, events); SystemMessg(packet, builder, client, events); SendChannels.SendChannelList(client); var timer = new System.Timers.Timer(5000); timer.AutoReset = true; timer.Elapsed += (sender, e) => { SendChannels.SendChannelList(client); }; timer.Start(); client.Metadata["timer"] = timer; } }
public static void GetCharacters(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { var server = (int)client.Metadata["server"]; var syncServer = client.Metadata["syncServer"] as SyncReceiver; var id = Authentication.GetUser(syncServer, (ulong)client.Metadata["magic"]); if (id <= 0) { client.Disconnect(); Log.Notice("Client disconnected!"); return; } client.AccountID = id; var characters = CharacterManagement.GetCharacters(syncServer, server, id); var subpass = SubpassManagement.GetSubpass(syncServer, id); var slotorder = CharacterManagement.GetSlotOrder(syncServer, server, id); if (slotorder == -1) { slotorder = 0x00123456; } client.Metadata["slotorder"] = slotorder; builder.New(0x85); { if (!subpass) { builder += 0; // not exist } else { builder += 1; // exists } builder += new byte[9]; builder += (byte)1; builder += 0; // selected char id builder += slotorder; builder += 8; //open 7th and 8th slot for (int i = 0; i < characters.Length; i++) { var charId = characters[i].id; var style = (uint)characters[i]._class; style += (uint)(characters[i].face << 8); style += (uint)(characters[i].colour << 13); style += (uint)(characters[i].hair << 17); style += (!characters[i].gender) ? 0 : (uint)(1 << 26); TimeSpan date = (characters[i].created - new DateTime(1970, 1, 1, 0, 0, 0)); var eq = characters[i].equipment; int head = (eq.head != null) ? (int)(BitConverter.ToUInt32(eq.head, 0) + (eq.head[0x02] * 0x2000)) : (ushort)0; int body = (eq.body != null) ? (int)(BitConverter.ToUInt32(eq.body, 0) + (eq.body[0x02] * 0x2000)) : (ushort)0; int hands = (eq.hands != null) ? (int)(BitConverter.ToUInt32(eq.hands, 0) + (eq.hands[0x02] * 0x2000)) : (ushort)0; int feet = (eq.feet != null) ? (int)(BitConverter.ToUInt32(eq.feet, 0) + (eq.feet[0x02] * 0x2000)) : (ushort)0; int righthand = (eq.righthand != null) ? (int)(BitConverter.ToUInt32(eq.righthand, 0) + (eq.righthand[0x02] * 0x2000)) : (ushort)0; int lefthand = (eq.lefthand != null) ? (int)(BitConverter.ToUInt32(eq.lefthand, 0) + (eq.lefthand[0x02] * 0x2000)) : (ushort)0; int back = (eq.back != null) ? (int)(BitConverter.ToUInt32(eq.back, 0) + (eq.back[0x02] * 0x2000)) : (ushort)0; builder += charId; builder += (long)date.TotalSeconds; // created builder += style; builder += characters[i].level; builder += 1; builder += 0; builder += 0; builder += (byte)0; builder += characters[i].map; builder += (ushort)characters[i].x; builder += (ushort)characters[i].y; builder += (long)head; builder += (long)0; builder += (long)body; builder += (long)0; builder += (long)hands; builder += (long)0; builder += (long)feet; builder += (long)0; builder += (long)righthand; builder += (long)0; builder += (long)lefthand; builder += (long)0; builder += (long)back; builder += (long)0; builder += new byte[588]; builder += (byte)(characters[i].name.Length + 1); builder += characters[i].name; builder += 0; builder += 0; builder += (byte)0; } } client.Send(builder, "GetMyChartr"); Authentication.UpdateOnline(syncServer, id, true); }
public static void Unknown_7D6(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { packet.Skip(4); var details = RSA.Decrypt(packet.ReadBytes(256)); var tmpdata = new byte[16]; Array.Copy(details, tmpdata, 16); var name = Encoding.UTF8.GetString(tmpdata).Trim('\0'); Array.Copy(details, 65, tmpdata, 0, 16); var pass = Encoding.UTF8.GetString(tmpdata).Trim('\0'); Log.Notice("Login authentication with name: " + name); var ip = client.RemoteEndPoint.ToString().Split(':')[0]; var syncServer = client.Metadata["syncServer"] as SyncReceiver; var data = Authentication.FetchAccount(syncServer, name, pass); var kick = false; if (data == null || data.id == -1) { builder.New(0x7D6); { builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.OutOfService; } events.FailedLogin("login.AuthAccount", new LoginEventArgs(name, pass, ip, LoginResult.OutOfService)); client.Send(builder, "Unknown_7D6"); return; } builder.New(0x7D6); { switch (data.status) { case AuthStatus.Unverified: builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Unverified; break; case AuthStatus.Banned: builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Banned; break; case AuthStatus.IncorrectName: case AuthStatus.IncorrectPass: builder += 0; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Incorrect; var tmp = data.status == AuthStatus.IncorrectName ? LoginResult.UnknownUsername : LoginResult.WrongPassword; events.FailedLogin("login.AuthAccount", new LoginEventArgs(name, pass, ip, tmp)); break; case AuthStatus.Verified: client.AccountID = data.id; Authentication.UpdateIPDate(syncServer, client.AccountID, ip, DateTime.Now); builder += 1; builder += 0; builder += (byte)0; builder += (int)AccountStatus.Normal; events.SuccessfulLogin("login.AuthAccount", new LoginEventArgs(name, pass, ip, LoginResult.Success, client.AccountID)); break; default: kick = true; break; } } client.Send(builder, "Unknown_7D6"); if (kick) { client.Disconnect(); } if (data.id > 0 && data.status == AuthStatus.Verified) { builder.New(0x7D6); { builder += 1; builder += 0x0700; builder += (byte)0; builder += (int)AccountStatus.Normal; builder += 0x2FD49F; builder += (byte)1; builder += 0x67; builder += (long)0; builder += (byte)0; builder += 0x55746A01; builder += (byte)0; builder += 1; builder += 0; builder += 0x02; builder += "A6318A0A7D294CE2A7019511FEDB7AD7"; // AuthKey builder += (short)0; builder += (byte)1; // Char Num of all servers builder += (byte)1; // Server ID builder += (byte)1; // CharNum } client.Send(builder, "Unknown_7D6"); URLToClient(packet, builder, client, events); SystemMessg(packet, builder, client, events); SendChannels.SendChannelList(client); var timer = new System.Timers.Timer(5000); timer.AutoReset = true; timer.Elapsed += (sender, e) => { SendChannels.SendChannelList(client); }; timer.Start(); client.Metadata["timer"] = timer; } }
/* * CheckVersion Packet * ------------------------- * Client2Server Structure: * * ushort : magic code * ushort : size * int : padding * ushort : opcode * * int : version1 #client version * int : version2 #debug * int : version3 #reserved * int : version4 #reserved * ------------------------- * Server2Client Structure: * * ushort : magic code * ushort : size * ushort : opcode * * int : version1 #client version * int : version2 #debug * int : version3 #reserved * int : version4 #reserved */ #endregion public static void CheckVersion(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { int version = packet.ReadInt(); var conf = client.Metadata["conf"] as Configuration; if (conf == null) { return; } int clientVersion = conf.ClientVersion; // i dont like this one, should be way better: client.GetIpAddress(); string ip = client.RemoteEndPoint.ToString().Split(':')[0]; bool kick = false; if (conf.Debug) { // skipping on debug mode builder.New(0x7A); { builder += version; // Client Version builder += 0; // Debug builder += 0; // Reserved builder += 0; // Reserved } events.VersionMismatch("login.CheckVersion", new VersionCheckEventArgs(version, ip, VersionCheckResult.Match)); client.Send(builder, "CheckVersion"); return; } var result = VersionCheckResult.None; if (version != clientVersion) { result = version > clientVersion ? VersionCheckResult.NewerClient : VersionCheckResult.OlderClient; kick = true; Log.Notice(string.Format("Failed CheckVersion Ip: {0} Client: {1}; Server: {2}", ip, version, clientVersion)); } else { result = VersionCheckResult.Match; } events.VersionMismatch("login.CheckVersion", new VersionCheckEventArgs(version, ip, result)); builder.New(0x7A); { builder += clientVersion; // Client Version builder += 0; // Debug builder += 0; // Reserved builder += 0; // Reserved } client.Send(builder, "CheckVersion"); if (kick) { // we have to be sure that client will be disconnected // if client didnt closed it's connection, server will close after 800ms var waitKick = new Timer(800); waitKick.Elapsed += (s, _e) => { client.Disconnect(); waitKick.Stop(); }; waitKick.Start(); return; } int id = -2; var sleep = new Timer(500); sleep.Elapsed += (s, _e) => { if (id == -2) { var syncServer = client.Metadata["syncServer"] as SyncReceiver; id = Authentication.GetUser(syncServer, (ulong)client.Metadata["magic"]); } if (id > 0) { client.AccountID = id; SendChannels.SendChannelList(client); var timer = new Timer(5000); timer.AutoReset = true; timer.Elapsed += (sender, e) => { SendChannels.SendChannelList(client); }; timer.Start(); client.Metadata["timer"] = timer; } sleep.Stop(); }; sleep.Start(); }
public static void MessageEvent(PacketReader packet, PacketBuilder builder, ClientHandler client, EventHandler events) { //byte[] b; var name = client.Metadata["name"] as string; var x = (ushort)client.Metadata["x"]; var y = (ushort)client.Metadata["y"]; var id = (uint)client.Metadata["id"]; var cid = (uint)client.Metadata["cid"]; var map = client.Metadata["map"] as IMap; int size = packet.ReadByte() - 3; packet.Skip(2); var type = packet.ReadByte(); var msg = packet.ReadString(size); var smsg = msg.Split(' '); if (msg == "/quit") { client.Disconnect(); return; } if (smsg.Length > 1 && smsg[0] == "/drop") { int itemid = 0; if (int.TryParse(smsg[1], out itemid)) { map.DropItem(x, y, itemid, cid, id); } return; } var clients = map.GetSurroundingClients(client, 1); if (smsg.Length > 1 && smsg[0] == "/spawn") { ushort mobid = 0; if (!ushort.TryParse(smsg[1], out mobid)) { return; } var p = client.CreatePacket("MobSpawned", mobid); client.Send(p, "MobSpawned"); return; } if (msg == "/partytime") { uint pid = 1337; foreach (var c in clients) { builder.New(0xC9); { builder += (int)pid; builder += (byte)12; //b = builder.Data; } var timestamp = (uint)c.Metadata["timestamp"]; var style = (uint)c.Metadata["style"]; c.Send(builder, "UnknownPacket_0xC9"); builder.New(0xC8); { builder += (short)0x3101; builder += (int)pid++; builder += (short)0x000D; builder += (short)0x0100; builder += 1; builder += Environment.TickCount - (int)timestamp; builder += (short)(x + 1); builder += (short)y; builder += (short)(x + 1); builder += (short)y; builder += (byte)0; builder += 0; builder += (short)0; builder += (int)style; builder += (byte)1; builder += (byte)0; builder += 0; builder += 0; builder += (byte)0; var equipment = (List <CItem>)c.Metadata["equipment"]; builder += (byte)(equipment.Count); builder += (short)0; builder += (byte)0; builder += 0; name = "PARTY TIME!!"; builder += (byte)(name.Length + 1); builder += name; builder += (byte)0; foreach (var e in equipment) { builder += (short)e.ID; builder += (byte)e.Slot; } //b = builder.Data; } c.Send(builder, "UnknownPacket_0xC8"); } return; } foreach (var c in clients) { builder.New(0xD9); { builder += (int)cid; builder += (byte)(msg.Length + 3); builder += (byte)0xFE; builder += (byte)0xFE; builder += type; builder += msg; //b = builder.Data; } c.Send(builder, "MessageEvnt"); } events.SaidLocal("world.700.MessageEvnt", (int)cid, name, msg); }