static void Main(string[] args) { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnexpectedExHandler); Console.CancelKeyPress += Console_CancelKeyPress; Logger.SetLogfile(false); MasterThread.Load("MPLRServer"); try { MySQL_Connection.Initialize(); } catch { Environment.Exit(12); } AccountDataCache.Initialize(); #if LOCALE_GMS GMSKeys.Initialize(); #endif CommandHandler.Initialize(); Timeline.Init(); Random = new System.Random(); { InitializeValidHeaders(); AcceptedIPs = new List<string>(); #if LOCALE_GMS AcceptedIPs.Add("8.31.9"); // GMS #elif LOCALE_EMS AcceptedIPs.Add("109.234.77"); // EMS #endif Clients = new List<ClientConnection>(); StartPinger(); StartCharacterDeleteQueue(); } EXPTable.Load(); SessionRestartCache.Start(); // For clients Acceptor accept = new Acceptor(ServerMapleInfo.MAPLER_PORT, sock => { new ClientConnection(sock); }); // For online check! byte[] OnlineCheckInfo = null; { MaplePacket packet = new MaplePacket(ServerMapleInfo.VERSION); packet.WriteByte(ServerMapleInfo.LOCALE); byte[] temp = packet.ToArray(); OnlineCheckInfo = new byte[temp.Length + 1]; Buffer.BlockCopy(temp, 0, OnlineCheckInfo, 1, temp.Length); OnlineCheckInfo[0] = (byte)(temp.Length + 4); packet.Dispose(); packet = null; } Acceptor acceptCheck = new Acceptor(ServerMapleInfo.MAPLER_PORT_SERVER_INFO, sock => { sock.Send(OnlineCheckInfo); sock.Send(BitConverter.GetBytes(Clients.Count)); sock.Shutdown(System.Net.Sockets.SocketShutdown.Both); sock.Close(); }); Logger.WriteLine("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"); Logger.WriteLine("| |"); Logger.WriteLine("| Mapler.me Server |"); Logger.WriteLine("| |"); #if LOCALE_GMS Logger.WriteLine("| GLOBAL |"); #elif LOCALE_EMS Logger.WriteLine("| EUROPE |"); #elif LOCALE_KMS Logger.WriteLine("| KOREA |"); #endif Logger.WriteLine("| |"); Logger.WriteLine("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"); Logger.WriteLine("| Build For: {0,3} Locale {1,1} |", ServerMapleInfo.VERSION, ServerMapleInfo.LOCALE); Logger.WriteLine("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"); Logger.WriteLine("Accepting connections on {0}, and info requests on {1}", ServerMapleInfo.MAPLER_PORT, ServerMapleInfo.MAPLER_PORT_SERVER_INFO); while (true) { string cmd = Console.ReadLine(); if (cmd == null) break; // CTRL + C string[] arguments = cmd.Split(' '); if (arguments.Length >= 1) { switch (arguments[0]) { #if LOCALE_GMS case "getkeys": { GMSKeys.Initialize(); break; } #endif case "reload_store": { MasterThread.Instance.AddCallback(a => { AccountDataCache.Instance.Load(); }); break; } case "request_screenshots": { MasterThread.Instance.AddCallback(a => { var tmp = new List<ClientConnection>(Clients); foreach (var client in tmp) { using (MaplePacket pack = new MaplePacket(MaplePacket.CommunicationType.ServerPacket, 0xEEFE)) { pack.SwitchOver(); client.SendPacket(pack); } } }); break; } case "testsession": { int accountid = arguments.Length > 1 ? Int32.Parse(arguments[1]) : -1; bool raw = arguments.Length > 2; var verp = new MSBLoader(); var connection = new ClientConnection(verp); connection.AccountID = accountid; verp.Parse("Savefile.msb", raw); break; } case "players": { string names = string.Join(", ", Clients); Console.WriteLine("Players online:\r\n{0}", names); break; } case "close": case "stop": case "exit": { MasterThread.Instance.AddCallback(a => { var tmp = new List<ClientConnection>(Clients); foreach (var client in tmp) { // client.Save(true, true); client.Disconnect(); } MySQL_Connection.Instance.Stop = true; MasterThread.Instance.Stop = true; }); break; } default: Console.WriteLine("Command not found"); break; } } } }
public static void Initialize() { Instance = new CommandHandler() { CommandHandlers = new Dictionary<string,Action<ClientConnection, string[]>>() }; Instance.CommandHandlers.Add("report", (pConnection, pArguments) => { return; // Disabled if (pArguments.Length == 1) { string name = pArguments[0]; if (name.Length > 12) return; bool found = false; string query = "SELECT name FROM character_views WHERE name LIKE '" + MySql.Data.MySqlClient.MySqlHelper.EscapeString(name) + "%' AND mapid = " + pConnection.CharData.Stats.MapID; using (var result = MySQL_Connection.Instance.RunQuery(query) as MySql.Data.MySqlClient.MySqlDataReader) { if (result.HasRows && result.Read()) { name = result.GetString(0); found = true; } else { pConnection.Logger_WriteLine("Could not find {0} for {1}", name, pConnection.CharData.Stats.Name); } } if (found) { using (InsertQueryBuilder iqb = new InsertQueryBuilder("reports")) { iqb.AddColumns(false, "id", "name", "reported_by", "reported_when", "mapid", "screenshot"); iqb.AddRow(null, name, pConnection.CharacterInternalID, new MySQL_Connection.NowType(), pConnection.CharData.Stats.MapID, null); int result = (int)MySQL_Connection.Instance.RunQuery(iqb.ToString()); if (result != 0) { pConnection.Logger_WriteLine("Reported {0} (by {1}). Requesting Screenshot...", name, pConnection.CharData.Stats.Name); using (MaplePacket pack = new MaplePacket(MaplePacket.CommunicationType.ServerPacket, (ushort)0xEEFE)) { pack.WriteString("http://mapler.me/actions/upload_report.php"); pack.WriteInt(MySQL_Connection.Instance.GetLastInsertId()); pack.SwitchOver(); pConnection.SendPacket(pack); } } else { pConnection.Logger_WriteLine("Report FAIL {0} (by {1})", name, pConnection.CharData.Stats.Name); } } } } }); }
void device_OnPacketArrival(object sender, CaptureEventArgs e) { var packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); // Check if IP packet IpPacket ipPacket = packet.Extract(typeof(IpPacket)) as IpPacket; if (ipPacket == null) return; if (!CheckIfCorrectIP(ipPacket.SourceAddress.ToString()) && !CheckIfCorrectIP(ipPacket.DestinationAddress.ToString())) { return; } TcpPacket tcpPacket = packet.Extract(typeof(TcpPacket)) as TcpPacket; if (tcpPacket == null) return; if (!FoundConnection) { if (tcpPacket.Syn && tcpPacket.Ack) { // Found new connection. // Check version... if (frmMain.Instance.CheckRunningEXEVersion()) { // Correct version FoundConnection = true; _currentPortMap = new KeyValuePair<ushort, ushort>(tcpPacket.DestinationPort, tcpPacket.SourcePort); _currentSession = new Session(); MasterThread.Instance.AddCallback((a) => { using (MaplePacket p = new MaplePacket(0xEE00)) { p.WriteBool(true); p.WriteString(ipPacket.SourceAddress.ToString()); p.WriteUShort(tcpPacket.SourcePort); p.SwitchOver(); p.Reset(0); ServerConnection.Instance.ForwardPacket(MaplePacket.CommunicationType.ClientPacket, p); } }); Logger.WriteLine("[CON] New connection found on {0}!", e.Device.Description); if (cache != 0) { _currentSession.SetOutboundSequence(cache); cache = 0; } _currentSession.BufferTCPPacket(tcpPacket, !(_currentPortMap.Key == tcpPacket.SourcePort && _currentPortMap.Value == tcpPacket.DestinationPort)); } else { Logger.WriteLine("Incorrect MapleStory version. Ignoring connection."); } } else if (tcpPacket.Syn && !tcpPacket.Ack) // Heh fix { cache = (int)(tcpPacket.SequenceNumber + 1); } } else if (FoundConnection && ( (_currentPortMap.Key == tcpPacket.SourcePort && _currentPortMap.Value == tcpPacket.DestinationPort) || (_currentPortMap.Value == tcpPacket.SourcePort && _currentPortMap.Key == tcpPacket.DestinationPort) ) ) { if (tcpPacket.Fin || tcpPacket.Rst) { FoundConnection = false; Logger.WriteLine("[CON] Connection Lost"); MasterThread.Instance.AddCallback((a) => { using (MaplePacket p = new MaplePacket(0xEE00)) { p.WriteBool(false); p.SwitchOver(); p.Reset(0); ServerConnection.Instance.ForwardPacket(MaplePacket.CommunicationType.ClientPacket, p); } }); return; } bool result = _currentSession.BufferTCPPacket(tcpPacket, !(_currentPortMap.Key == tcpPacket.SourcePort && _currentPortMap.Value == tcpPacket.DestinationPort)); if (!result) { FoundConnection = false; _currentSession.Dispose(); _currentSession = null; } } else { // Logger.WriteLine("[DEBUG] {0} - {1} {2}", FoundConnection, tcpPacket.SourcePort, tcpPacket.DestinationPort); } }
public override void OnPacket(MaplePacket pPacket) { MasterThread.Instance.AddCallback((a) => { try { if (Disconnected) return; // Just to be sure... if (_exporter != null) _exporter.AddPacket(pPacket); MaplePacket.CommunicationType type = (MaplePacket.CommunicationType)pPacket.ReadByte(); ushort opcode = pPacket.ReadUShort(); if (IsFake) { Logger.WriteLine("Emulating {0:X4} (Len: {1})", opcode, pPacket.Length); } if ((byte)type < Program.ValidHeaders.Length) { // Check if packet is accepted var list = Program.ValidHeaders[(byte)type]; if (list.ContainsKey(opcode)) { var action = list[opcode]; if (action != null) { try { if (action.CanHandle == null || action.CanHandle(this)) action.Handle(this, pPacket); } catch (Exception ex) { Logger_ErrorLog("Failed parsing {0:X4} for {1}", opcode, type); Logger_WriteLine(ex.ToString()); if (!IsFake) { LogFilename += "ERROR"; SendInfoText("An error occurred on the Mapler.me server! Please report this :)"); // Save exception to packet using (MaplePacket mp = new MaplePacket(MaplePacket.CommunicationType.ServerPacket, 0x9999)) { mp.WriteString(ex.ToString()); if (ex.ToString().Contains("MySql.Data.MySqlClient.MySqlException")) { Logger_ErrorLog("MySQL exception!"); var queries = MySQL_Connection.Instance.GetRanQueries(); mp.WriteInt(queries.Count); foreach (var kvp in queries) { mp.WriteString(kvp.Key); mp.WriteString(kvp.Value); } } mp.SwitchOver(); // Make read packet _exporter.AddPacket(mp); } Save(false, false); } } } else { if (!IsFake) Logger_WriteLine("No action for {0:X4}", opcode); } } else { if (!IsFake) Logger_WriteLine("Client sent packet {0:X4} for {1} but this one is not handled!", opcode, type); } } else { Logger_ErrorLog("Packet Type not accepted!!! {0:X4} {1}", opcode, (byte)type); } } catch (Exception ex) { Logger.ErrorLog("Failed handling packet: {0}", ex.ToString()); SendInfoText("An error occurred on the Mapler.me server! Please report this :)"); } pPacket.Dispose(); pPacket = null; }); }
public void Parse(string pFile, bool pMapleSharkFile) { using (FileStream stream = new FileStream(pFile, FileMode.Open, FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); if (reader.ReadUInt16() != 0x2020) { return; } string ip2 = reader.ReadString(); // Local Endpoint ushort port2 = reader.ReadUInt16(); // Port string ip = reader.ReadString(); // Remote Endpoint ushort port = reader.ReadUInt16(); // Port byte locale = reader.ReadByte(); // Locale ushort version = reader.ReadUInt16(); // Version Logger.WriteLine("Emulating socket connection with connection from V{0}", version / 100); MaplePacket p; if (pMapleSharkFile) { if (ip.Contains(":")) { // Shit. ip = "1.2.3.4"; } p = new MaplePacket(MaplePacket.CommunicationType.ClientPacket, 0xEE00); p.WriteBool(true); p.WriteString(ip); p.WriteUShort(port); p.SwitchOver(); p.Reset(0); PacketHandler(p); } while (stream.Position < stream.Length) { long timestamp = reader.ReadInt64(); ushort size = reader.ReadUInt16(); ushort opcode = reader.ReadUInt16(); bool outbound = reader.ReadBoolean(); byte[] buffer = new byte[3 + size]; buffer[0] = (byte)(outbound ? MaplePacket.CommunicationType.ClientPacket : MaplePacket.CommunicationType.ServerPacket); Buffer.BlockCopy(BitConverter.GetBytes(opcode), 0, buffer, 1, 2); Buffer.BlockCopy(reader.ReadBytes(size), 0, buffer, 3, size); if (opcode >= 0xEE00) continue; // Ignore! MaplePacket packet = new MaplePacket(buffer); try { if (PacketHandler != null) PacketHandler(packet); } catch (Exception ex) { Logger.WriteLine("Internal Packet Handling Exception"); throw new Exception("Internal Packet Handling Exception", ex); } } if (pMapleSharkFile) { p = new MaplePacket(MaplePacket.CommunicationType.ClientPacket, 0xEE00); p.WriteBool(false); p.SwitchOver(); p.Reset(0); PacketHandler(p); } } DisconnectHandler(); }