public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { if (Global.FixWaterTampleTeleport) { pck.ReadUInt32(); byte teleport_type = pck.ReadUInt8(); if (teleport_type == 2) { uint teleport_id = pck.ReadUInt32(); string cname = session.State["charname"] as string; if (cname.Length == 0) { Global.logmgr.WriteLog(LogLevel.Warning, "charname len == 0 ! (teleport fix)"); return PacketProcessResult.ContinueLoop; } //проверка прав доступа на второй уровень if (teleport_id == 166 || teleport_id == 167) { if (Global.dbmgr.AnticheatCheckTeleportAccess(cname, (int)teleport_id) == 0) { session.SendClientNotice("UIIT_STT_ANTICHEAT_TELEPORT_TAMPLE"); return PacketProcessResult.ContinueLoop; } } } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleModule(Packet pck, RelaySession session, SilkroadServer server) { if (Global.EnableArenaStatusNotify) { if (pck.ReadInt8() == 9) { pck.ReadInt8(); int status = pck.ReadInt8(); string cname = session.State["charname"] as string; //передаем в базу данные о статусе боя Global.dbmgr.AnticheatArenaStatusNotify(cname, status); if (status == 1) { //Вам бЫли начислены очки славы textu'system lel ye perfect. session.SendClientNotice("UIIT_STT_ANTICHEAT_ADDED_HONOR_POINT"); } else { //Вы потеряли очки славы session.SendClientNotice("UIIT_STT_ANTICHEAT_MISSING_HONOR_POINT"); } } } return PacketProcessResult.DoNothing; }
//constructors public Packet(Packet rhs) { lock (rhs.m_lock) { m_lock = new object(); m_opcode = rhs.m_opcode; m_encrypted = rhs.m_encrypted; m_massive = rhs.m_massive; m_locked = rhs.m_locked; if (!m_locked) { m_writer = new PacketWriter(); m_reader = null; m_reader_bytes = null; m_writer.Write(rhs.m_writer.GetBytes()); } else { m_writer = null; m_reader_bytes = rhs.m_reader_bytes; m_reader = new PacketReader(m_reader_bytes); } } }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session) { byte locale = pck.ReadUInt8(); string username = pck.ReadAscii(); string password = pck.ReadAscii(); ushort ServerID = pck.ReadUInt16(); //проверить if (Global.EnableIpAccountLimitation) { int nResult = Global.dbmgr.GetIpLimitationResult(username, Utility.GetRemoteEpString(session.Arguments.ClientSocket)); if (nResult == 0) { Packet login_response = new Packet(0xA102, false); login_response.WriteUInt8(0x02); login_response.WriteUInt8(12); session.SendPacketToClient(login_response); //drop conn return PacketProcessResult.Disconnect; } } if (Global.EnableLoginProcessing) { Packet login = new Packet(0x6102); login.WriteUInt8(Global.OriginalLocale > 0 && locale > 0 ? Global.OriginalLocale : locale); login.WriteAscii(username); login.WriteAscii(Global.EnableUseSha1Salt ? Utility.HashPassword(username, password) : password); login.WriteUInt16(ServerID); session.SendPacketToModule(login); //return PacketProcessResult.DoNothing; return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { string name = pck.ReadAscii(); session.State["charname"] = name; session.State["level"] = Global.dbmgr.getCharLvl(name); return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { if (Global.UseSafeRegion) { bool isSafe = false; bool.TryParse(session.State["isSafe"] as string, out isSafe); bool isBot = false; bool.TryParse(session.State["isBot"] as string, out isBot); //Запрет использования скилов в регионе if (isSafe) { if (pck.ReadUInt8() == 1) { //запрет на использование скилов и (обычная атака ==1) if (pck.ReadUInt8() == 4) { session.SendClientNotice("UIIT_STT_ANTICHEAT_USE_SKILL"); return PacketProcessResult.ContinueLoop; } } } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { int level = 0; int.TryParse(session.State["level"] as string, out level); if(Global.ArenaRegistrationLevel > level && Global.ArenaRegistrationLevel > 0) { session.SendClientNotice("UIIT_STT_ANTICHEAT_ARENA_LEVEL"); return PacketProcessResult.ContinueLoop; } if (Global.DisableBotArenaRegistration) { bool isBot = false; bool.TryParse(session.State["isBot"] as string, out isBot); //регистрация на арену if (isBot) { session.SendClientNotice("UIIT_STT_ANTICHEAT_USE_FUNCTION"); return PacketProcessResult.ContinueLoop; } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { byte locale = pck.ReadUInt8(); string username = pck.ReadAscii(); string password = pck.ReadAscii(); ushort ServerID = pck.ReadUInt16(); if (Global.EnableServerInspection && !Global.InspectionLoginIgnore.Contains(username)) { Packet login_response = new Packet(0xA102, false); login_response.WriteUInt8(0x02); login_response.WriteUInt8(0x02); login_response.WriteUInt8(0x02); session.SendPacketToClient(login_response); return PacketProcessResult.Disconnect; } if (Global.EnableIpAccountLimitation) { //We use Utility.GetRemoteEpString because username is assigned after AgentServer.UserAuth string clientAddr = Utility.GetRemoteEpString(session.Arguments.ClientSocket); int connectionCount = Global.srvmgr.GetUserCountByIpForAgent(clientAddr); if (connectionCount >= Global.AccountIpLimitCount) { Packet login_resp = new Packet(0xA102, false); login_resp.WriteUInt8(0x02); login_resp.WriteUInt8(12); session.SendPacketToClient(login_resp); return PacketProcessResult.Disconnect; } } int serverOnline = 0; int.TryParse(session.State["server_" + ServerID] as string, out serverOnline); if (Global.ShardMaxOnline > 0 && Global.ShardMaxOnline <= serverOnline) { Packet login_response = new Packet(0xA102, false); login_response.WriteUInt8(0x02); login_response.WriteUInt8(5); session.SendPacketToClient(login_response); return PacketProcessResult.Disconnect; } if (Global.EnableLoginProcessing) { Packet login = new Packet(0x6102); login.WriteUInt8(Global.OriginalLocale > 0 && locale > 0 ? Global.OriginalLocale : locale); login.WriteAscii(username); login.WriteAscii(Global.EnableUseSha1Salt ? Utility.HashPassword(username, password) : password); login.WriteUInt16(ServerID); session.SendPacketToModule(login); //return PacketProcessResult.DoNothing; return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
private void btnDebugCharacterData_Click(object sender, EventArgs e) { SilkroadSecurityApi.Packet _0x3013Packet = DebugPacket.LoadPacketFormFile(0x3013); SilkroadSecurityApi.Packet _0x3020Packet = DebugPacket.LoadPacketFormFile(0x3020); SroBasic.Controllers.ParsePacket._0x3013.DoWork(_0x3013Packet); SroBasic.Controllers.ParsePacket._0x3020.DoWork(_0x3020Packet); }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { if (Global.DisableAcademyInvite) { session.SendClientNotice("UIIT_STT_ANTICHEAT_DISABLE_ACADEMY_INVITE"); return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { string charname = session.State["charname"] as string; if (Global.MaxGuildInUnion > 0 && Global.dbmgr.GuildMembers(charname, 2, Global.MaxGuildInUnion) == 0) { session.SendClientNotice("UIIT_STT_ANTICHEAT_MAX_GUILD_IN_UNION"); return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
public void BroadcastPacketToServerClients(Packet pck, ServerType srvtype) { foreach (var srv in m_servers) { if (srv.SrvType == srvtype) { srv.BroadcastClientPacket(pck); } } }
public static void HandleDelayedPacket(SilkroadServer server, string noticeText) { if (server.SessionCount > 0) { Packet notice = new Packet(0x3026); notice.WriteUInt8(7); notice.WriteAscii(noticeText,Global.TextEncodeCode); //Only chars which are logged in for 60 seconds will receive the message server.BroadcastToLoggedInChars(notice, Global.AutoNoticeSendBeginDelay); } }
/// <summary> /// Sends C -> S 0x6323 packet instead of user /// </summary> /// <param name="pck"></param> /// <param name="session"></param> /// <returns></returns> public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { if (Global.EnableAutoCaptcha) { Packet p = new Packet(0x6323, false); p.WriteAscii(Global.AutoCaptchaValue); // m_ModuleSecurity.Send(p); session.SendPacketToModule(p); return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { uint type = pck.ReadUInt8(); string key = pck.ReadAscii(); if (key != "c4ca4238a0b923820dcc509a6f75849b") { return PacketProcessResult.ContinueLoop; } if(type == 9) { Global.srvmgr.StopAllContexts(); } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleModule(Packet pck, RelaySession session, SilkroadServer server) { if (server.HasAgentRedirectRules()) { string src_host; int src_port; byte flag1 = pck.ReadUInt8(); if (flag1 == 1) { UInt32 uint1 = pck.ReadUInt32(); src_host = pck.ReadAscii(); src_port = pck.ReadUInt16(); bool redirectRuleFound = false; for (int j = 0; j < server.RedirectRules.Count; j++) { if (server.RedirectRules[j].OriginalIp == src_host && server.RedirectRules[j].OriginalPort == src_port) { Packet mypck = new Packet(0xA102, false); mypck.WriteUInt8(flag1); mypck.WriteUInt32(uint1); mypck.WriteAscii(server.RedirectRules[j].NewIp); mypck.WriteUInt16((ushort)server.RedirectRules[j].NewPort); // m_ClientSecurity.Send(mypck); session.SendPacketToClient(mypck); redirectRuleFound = true; break; } } if (!redirectRuleFound) { Global.logmgr.WriteLog(LogLevel.Warning, "Agent redirect rules given, but [{0}:{1}] is unknown agent server", src_host, src_port); } else { return PacketProcessResult.ContinueLoop; } } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { UInt32 uint32_1 = pck.ReadUInt32(); string uname = pck.ReadAscii(); string passw = pck.ReadAscii(); byte locale = pck.ReadUInt8(); uint ukn1 = pck.ReadUInt32(); uint ukn = pck.ReadUInt16(); if (uname.Contains("'")) { Global.logmgr.WriteLog(LogLevel.Error, "User trying to exploit username: {0}", uname); return PacketProcessResult.Disconnect; } //инициализурем данные session.State["username"] = uname; session.State["isBot"] = false; session.State["isSafe"] = false; session.State["noticeDone"] = false; session.State["lastExchange"] = DateTime.Now; session.State["lastLogOut"] = DateTime.Now; session.State["lastStall"] = DateTime.Now; session.State["proper_logout"] = false; session.State["level"] = 0; //пишем в базу что юзер залогинился Global.dbmgr.AnticheatAuthLog(uname, session.State["ip_address"] as string); Global.logmgr.WriteLog(LogLevel.Notify, "User logged in [{0}]", uname); if (Global.EnableBotDetected && locale == Global.OriginalLocale) { session.State["isBot"] = true; } if (Global.EnableLoginProcessing) { Packet p = new Packet(0x6103); p.WriteUInt32(uint32_1); p.WriteAscii(uname); p.WriteAscii(Global.EnableUseSha1Salt ? Utility.HashPassword(uname, passw) : passw); p.WriteUInt8(Global.OriginalLocale > 0 && locale > 0 ? Global.OriginalLocale : locale); p.WriteUInt32(ukn1); p.WriteUInt16(ukn); // m_ModuleSecurity.Send(p); session.SendPacketToModule(p); return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { //лоток if (Global.EnableStallCooldown) { if (Convert.ToDateTime(session.State["lastStall"]) < DateTime.Now) { session.State["lastStall"] = DateTime.Now.AddSeconds(Global.StallCooldownInSecond); } else { session.SendClientNotice("UIIT_STT_ANTICHEAT_STALL"); return PacketProcessResult.ContinueLoop; } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { if (Global.EnableGmAccessControl) { //Делаем запрос в базу и проверяем разрешеная ли команда uint commandID = pck.ReadUInt16(); string uname = session.State["username"] as string; if (Global.dbmgr.checkGmAccessControl(uname, commandID) == 1) { if (commandID == 6 || commandID == 7) { //Делаем проверку на разрешение использовать этот ID uint obj_id = pck.ReadUInt32(); uint amountOrOptLevel = pck.ReadUInt8(); if (Global.dbmgr.checkGmObjAccessControl(uname, obj_id, amountOrOptLevel) == 0) { session.SendClientNotice("UIIT_STT_ANTICHEAT_GM_USE_CREATE"); return PacketProcessResult.ContinueLoop; } } //Убираем возможность полноценно килять мобов гму. if (commandID == 20) { uint k_mob_id = pck.ReadUInt32(); Packet p = new Packet(0x7010); p.WriteUInt16(20); p.WriteUInt32(k_mob_id); p.WriteUInt8(1); session.SendPacketToModule(p); return PacketProcessResult.ContinueLoop; } } else { session.SendClientNotice("UIIT_STT_ANTICHEAT_GM_USE_COMMAND"); return PacketProcessResult.ContinueLoop; } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { if (Global.EnableLogOutCooldown) { if (Convert.ToDateTime(session.State["lastLogOut"]) < DateTime.Now) { session.State["lastLogOut"] = DateTime.Now.AddSeconds(Global.LogOutCooldownInSecond); } else { session.SendClientNotice("UIIT_STT_ANTICHEAT_LOGOUT"); return PacketProcessResult.ContinueLoop; } } session.State["proper_logout"] = true; return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleModule(Packet pck, RelaySession session, SilkroadServer server) { Packet ServerList = new Packet(0xA101); byte GlobalOperationFlag = pck.ReadUInt8(); ServerList.WriteUInt8(GlobalOperationFlag); while (GlobalOperationFlag == 1) { byte GlobalOperationType = pck.ReadUInt8(); string GlobalOperationName = pck.ReadAscii(); GlobalOperationFlag = pck.ReadUInt8(); ServerList.WriteUInt8(GlobalOperationType); ServerList.WriteAscii(GlobalOperationName); ServerList.WriteUInt8(GlobalOperationFlag); } byte ShardFlag = pck.ReadUInt8(); ServerList.WriteUInt8(ShardFlag); while (ShardFlag == 1) { uint ShardID = pck.ReadUInt16(); string ShardName = pck.ReadAscii(); uint ShardCurrent = pck.ReadUInt16(); uint ShardCapacity = pck.ReadUInt16(); byte ShardStatus = pck.ReadUInt8(); byte GlobalOperationID = pck.ReadUInt8(); ShardFlag = pck.ReadUInt8(); session.State["server_" + ShardID] = ShardCurrent; ServerList.WriteUInt16(ShardID); ServerList.WriteAscii("Возрождение", Global.TextEncodeCode); ServerList.WriteUInt16(ShardCurrent + Global.ShardFakeOnline); ServerList.WriteUInt16(Global.ShardMaxOnline > 0 ? (uint)Global.ShardMaxOnline : ShardCapacity); ServerList.WriteUInt8(ShardStatus); ServerList.WriteUInt8(GlobalOperationID); ServerList.WriteUInt8(ShardFlag); } session.SendPacketToClient(ServerList); return PacketProcessResult.ContinueLoop; }
public static PacketProcessResult HandleModule(Packet pck, RelaySession session, SilkroadServer server) { if (Global.EnableLoginNotice) { bool noticeDone = false; bool.TryParse(session.State["noticeDone"] as string, out noticeDone); if (!noticeDone) { foreach (string text in Global.LoginNotice) { Packet notice = new Packet(0x3026); notice.WriteUInt8(7); notice.WriteAscii(text, Global.TextEncodeCode); session.SendPacketToClient(notice); } session.State["noticeDone"] = true; } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleModule(Packet pck, RelaySession session, SilkroadServer server) { uint type = pck.ReadUInt16(); if (Global.EnableUniqueDeathNotify && type == 3078) { uint mob_id = pck.ReadUInt32(); string char_name = pck.ReadAscii(); //Проверяем тормоз, дабы с каждого потока не спамило if(Global.UniqueDeathNotifyName == char_name && Global.UniqueDeathNotifyID == mob_id && Global.UniqueDeathNotifyTime > DateTime.Now) { return PacketProcessResult.DoNothing; } Global.UniqueDeathNotifyName = char_name; Global.UniqueDeathNotifyID = mob_id; Global.UniqueDeathNotifyTime = DateTime.Now.AddSeconds(10); Global.dbmgr.UniqueDeathNotify(char_name, (int)mob_id); } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleModule(Packet pck, RelaySession session, SilkroadServer server) { if (Global.EnableStartIntro) { byte hz1 = pck.ReadUInt8(); if (hz1 == 1) { ulong hz2 = pck.ReadUInt64(); if (hz2 == 1) { Packet intro = new Packet(0x3CA2); intro.WriteAscii(Global.StartIntroScriptName); intro.WriteUInt32(12); session.SendPacketToClient(intro); } } return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleModule(Packet pck, RelaySession session, SilkroadServer server) { bool isBot = false; bool.TryParse(session.State["isBot"] as string, out isBot); if (Global.UseSafeRegion && isBot) { pck.ReadUInt32(); pck.ReadUInt8(); int region = pck.ReadUInt16(); if (Global.SafeRegions.Contains(region)) { session.State["isSafe"] = true; } else { session.State["isSafe"] = false; } } return PacketProcessResult.DoNothing; }
public static PacketProcessResult HandleClient(Packet pck, RelaySession session, SilkroadServer server) { if (Global.EnableItemMallBuyFix) { Packet MyResponse = new Packet(0xB566, true); string uname = session.State["username"] as string; if (uname.Length == 0) { Global.logmgr.WriteLog(LogLevel.Warning, "username len == 0 !"); return PacketProcessResult.Disconnect; } if (uname.Contains("'")) { Global.logmgr.WriteLog(LogLevel.Warning, "User trying to exploit shop ! Uname str: {0}", uname); return PacketProcessResult.Disconnect; } List<string> query_res = Global.dbmgr.GetJidAndToken(uname); UInt32 jid = uint.Parse(query_res[0]); string token = query_res[1]; MyResponse.WriteUInt8(1); MyResponse.WriteUInt32(jid); MyResponse.WriteAscii(token); session.SendPacketToClient(MyResponse); // Global.g_LogManager.WriteLog(LogLevel.Notify, "Shop packet OK [{0}] JID [{1}] TOKEN [{2}]",uname,jid,token); return PacketProcessResult.ContinueLoop; } return PacketProcessResult.DoNothing; }
void GenerateSecurity(SecurityFlags flags) { m_security_flag = FromSecurityFlags(flags); m_security_flags = flags; m_client_security = true; //don't need about solving problem CA2000 Packet response = new Packet(0x5000); response.WriteUInt8(m_security_flag); if (m_security_flags.blowfish == 1) { m_initial_blowfish_key = NextUInt64(); m_blowfish.Initialize(BitConverter.GetBytes(m_initial_blowfish_key)); response.WriteUInt64(m_initial_blowfish_key); } if (m_security_flags.security_bytes == 1) { m_seed_count = NextUInt8(); SetupCountByte(m_seed_count); m_crc_seed = NextUInt8(); response.WriteUInt32(m_seed_count); response.WriteUInt32(m_crc_seed); } if (m_security_flags.handshake == 1) { m_handshake_blowfish_key = NextUInt64(); m_value_x = NextUInt32() & 0x7FFFFFFF; m_value_g = NextUInt32() & 0x7FFFFFFF; m_value_p = NextUInt32() & 0x7FFFFFFF; m_value_A = G_pow_X_mod_P(m_value_p, m_value_x, m_value_g); response.WriteUInt64(m_handshake_blowfish_key); response.WriteUInt32(m_value_g); response.WriteUInt32(m_value_p); response.WriteUInt32(m_value_A); } m_outgoing_packets.Add(response); }
// Default constructor public Security() { m_value_x = 0; m_value_g = 0; m_value_p = 0; m_value_A = 0; m_value_B = 0; m_value_K = 0; m_seed_count = 0; m_crc_seed = 0; m_initial_blowfish_key = 0; m_handshake_blowfish_key = 0; m_count_byte_seeds = new byte[3]; m_count_byte_seeds[0] = 0; m_count_byte_seeds[1] = 0; m_count_byte_seeds[2] = 0; m_client_key = 0; m_challenge_key = 0; m_client_security = false; m_security_flag = 0; m_security_flags = new SecurityFlags(); m_accepted_handshake = false; m_started_handshake = false; m_identity_flag = 0; m_identity_name = "SR_Client"; m_outgoing_packets = new List<Packet>(); m_incoming_packets = new List<Packet>(); m_enc_opcodes = new List<ushort>(); m_enc_opcodes.Add(0x2001); m_enc_opcodes.Add(0x6100); m_enc_opcodes.Add(0x6101); m_enc_opcodes.Add(0x6102); m_enc_opcodes.Add(0x6103); m_enc_opcodes.Add(0x6107); m_blowfish = new Blowfish(); m_recv_buffer = new TransferBuffer(8192); // must be at minimal 2 bytes! m_current_buffer = null; m_massive_count = 0; m_massive_packet = null; m_class_lock = new object(); }
protected virtual void Dispose(bool disposeManagedResources) { if (!this.disposed) { if (disposeManagedResources) { if (m_massive_packet != null) { m_massive_packet.Dispose(); m_massive_packet = null; } if (m_incoming_packets != null) { for (int i = 0; i < m_incoming_packets.Count; i++) { m_incoming_packets[i].Dispose(); m_incoming_packets[i] = null; } m_incoming_packets = null; } if (m_outgoing_packets != null) { for (int i = 0; i < m_outgoing_packets.Count; i++) { m_outgoing_packets[i].Dispose(); m_outgoing_packets[i] = null; } m_outgoing_packets = null; } } disposed = true; } }
// Queues a packet for processing to be sent. The data is simply formatted and processed during // the next call to TransferOutgoing. public void Send(Packet packet) { if (packet.Opcode == 0x5000 || packet.Opcode == 0x9000) { throw (new Exception("[SecurityAPI::Send] Handshake packets cannot be sent through this function.")); } lock (m_class_lock) { m_outgoing_packets.Add(packet); } }
// Transfers raw incoming data into the security object. Call TransferIncoming to // obtain a list of ready to process packets. public void Recv(TransferBuffer raw_buffer) { List<TransferBuffer> incoming_buffers_tmp = new List<TransferBuffer>(); lock (m_class_lock) { int length = raw_buffer.Size - raw_buffer.Offset; int index = 0; while (length > 0) { int max_length = length; int calc_length = m_recv_buffer.Buffer.Length - m_recv_buffer.Size; if (max_length > calc_length) { max_length = calc_length; } length -= max_length; Buffer.BlockCopy(raw_buffer.Buffer, raw_buffer.Offset + index, m_recv_buffer.Buffer, m_recv_buffer.Size, max_length); m_recv_buffer.Size += max_length; index += max_length; // Loop while we have data to process while (m_recv_buffer.Size > 0) { // If we do not have a current packet object, try to allocate one. if (m_current_buffer == null) { // We need at least two bytes to allocate a packet. if (m_recv_buffer.Size < 2) { break; } // Calculate the packet size. int packet_size = m_recv_buffer.Buffer[1] << 8 | m_recv_buffer.Buffer[0]; // Check to see if this packet is encrypted. if ((packet_size & 0x8000) > 0) { // If so, calculate the total payload size. packet_size &= 0x7FFF; // Mask off the encryption. if (m_security_flags.blowfish == 1) { packet_size = 2 + m_blowfish.GetOutputLength(packet_size + 4); } else { packet_size += 6; } } else { // The packet is unencrypted. The final size is simply // header size + payload size. packet_size += 6; } // Allocate the final buffer the packet will be written to m_current_buffer = new TransferBuffer(packet_size, 0, packet_size); } // Calculate how many bytes are left to receive in the packet. int max_copy_count = m_current_buffer.Size - m_current_buffer.Offset; // If we need more bytes than we currently have, update the size. if (max_copy_count > m_recv_buffer.Size) { max_copy_count = m_recv_buffer.Size; } // Copy the buffer data to the packet buffer Buffer.BlockCopy(m_recv_buffer.Buffer, 0, m_current_buffer.Buffer, m_current_buffer.Offset, max_copy_count); // Update how many bytes we now have m_current_buffer.Offset += max_copy_count; m_recv_buffer.Size -= max_copy_count; // If there is data remaining in the buffer, copy it over the data // we just removed (sliding buffer). if (m_recv_buffer.Size > 0) { Buffer.BlockCopy(m_recv_buffer.Buffer, max_copy_count, m_recv_buffer.Buffer, 0, m_recv_buffer.Size); } // Check to see if the current packet is now complete. if (m_current_buffer.Size == m_current_buffer.Offset) { // If so, dispatch it to the manager class for processing by the system. m_current_buffer.Offset = 0; incoming_buffers_tmp.Add(m_current_buffer); // Set the current packet to null so we can process the next packet // in the stream. m_current_buffer = null; } else { // Otherwise, we are done with this loop, since we need more // data for the current packet. break; } } } if (incoming_buffers_tmp.Count > 0) { foreach (TransferBuffer buffer in incoming_buffers_tmp) { PacketReader packet_data = null; try { bool packet_encrypted = false; int packet_size = buffer.Buffer[1] << 8 | buffer.Buffer[0]; if ((packet_size & 0x8000) > 0) { if (m_security_flags.blowfish == 1) { packet_size &= 0x7FFF; packet_encrypted = true; } else { packet_size &= 0x7FFF; } } if (packet_encrypted) { byte[] decrypted = m_blowfish.Decode(buffer.Buffer, 2, buffer.Size - 2); byte[] new_buffer = new byte[6 + packet_size]; Buffer.BlockCopy(BitConverter.GetBytes((ushort)packet_size), 0, new_buffer, 0, 2); Buffer.BlockCopy(decrypted, 0, new_buffer, 2, 4 + packet_size); buffer.Buffer = null; buffer.Buffer = new_buffer; } packet_data = new PacketReader(buffer.Buffer); packet_size = packet_data.ReadUInt16(); ushort packet_opcode = packet_data.ReadUInt16(); byte packet_security_count = packet_data.ReadByte(); byte packet_security_crc = packet_data.ReadByte(); // Client object whose bytes the server might need to verify if (m_client_security) { if (m_security_flags.security_bytes == 1) { byte expected_count = GenerateCountByte(true); if (packet_security_count != expected_count) { throw (new Exception("[SecurityAPI::Recv] Count byte mismatch.")); } if (packet_encrypted || (m_security_flags.security_bytes == 1 && m_security_flags.blowfish == 0)) { if (packet_encrypted || m_enc_opcodes.Contains(packet_opcode)) { packet_size |= 0x8000; Buffer.BlockCopy(BitConverter.GetBytes((ushort)packet_size), 0, buffer.Buffer, 0, 2); } } buffer.Buffer[5] = 0; byte expected_crc = GenerateCheckByte(buffer.Buffer); if (packet_security_crc != expected_crc) { throw (new Exception("[SecurityAPI::Recv] CRC byte mismatch.")); } buffer.Buffer[4] = 0; if (packet_encrypted || (m_security_flags.security_bytes == 1 && m_security_flags.blowfish == 0)) { if (packet_encrypted || m_enc_opcodes.Contains(packet_opcode)) { packet_size &= 0x7FFF; Buffer.BlockCopy(BitConverter.GetBytes((ushort)packet_size), 0, buffer.Buffer, 0, 2); } } } } if (packet_opcode == 0x5000 || packet_opcode == 0x9000) // New logic processing! { Handshake(packet_opcode, packet_data, packet_encrypted); // Pass the handshake packets to the user so they can at least see them. // They do not need to actually do anything with them. This was added to // help debugging and make output logs complete. //CA2000 dont care Packet packet = new Packet(packet_opcode, packet_encrypted, false, buffer.Buffer, 6, packet_size); packet.Lock(); m_incoming_packets.Add(packet); } else { if (m_client_security) { // Make sure the client accepted the security system first if (!m_accepted_handshake) { throw (new Exception("[SecurityAPI::Recv] The client has not accepted the handshake.")); } } if (packet_opcode == 0x600D) // Auto process massive messages for the user { byte mode = packet_data.ReadByte(); if (mode == 1) { m_massive_count = packet_data.ReadUInt16(); ushort contained_packet_opcode = packet_data.ReadUInt16(); m_massive_packet = new Packet(contained_packet_opcode, packet_encrypted, true); } else { if (m_massive_packet == null) { throw (new Exception("[SecurityAPI::Recv] A malformed 0x600D packet was received.")); } m_massive_packet.WriteUInt8Array(packet_data.ReadBytes(packet_size - 1)); m_massive_count--; if (m_massive_count == 0) { m_massive_packet.Lock(); m_incoming_packets.Add(m_massive_packet); m_massive_packet = null; } } } else { //CA2000 dont care Packet packet = new Packet(packet_opcode, packet_encrypted, false, buffer.Buffer, 6, packet_size); packet.Lock(); m_incoming_packets.Add(packet); } } } finally { if (packet_data != null) { packet_data.Close(); } } } } } }