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 override void OnPacket(MaplePacket pPacket) { byte type = pPacket.ReadByte(); ushort header = pPacket.ReadUShort(); if (header >= 0xEE00) { if (header == 0xEEFF) { string version = pPacket.ReadString(); if (version != Logger.Version) { if (frmMain.Instance != null) { frmMain.Instance.Invoke((System.Windows.Forms.MethodInvoker)delegate { System.Windows.Forms.MessageBox.Show(frmMain.Instance, "You are using an outdated version of Mapler.me! Check the site for the latest updates.", "Mapler.me server connection error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); }); } else { System.Windows.Forms.MessageBox.Show("You are using an outdated version of Mapler.me! Check the site for the latest updates.", "Mapler.me server connection error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } Environment.Exit(3); return; } // Crypto byte[] sendkey = pPacket.ReadBytes(32), recvkey = pPacket.ReadBytes(32); SetKeys(sendkey, recvkey); _validHeaders = new List<ushort>[(byte)MaplePacket.CommunicationType.AMOUNT]; for (byte i = 0; i < (byte)MaplePacket.CommunicationType.AMOUNT; i++) { _validHeaders[i] = new List<ushort>(); for (ushort j = pPacket.ReadUShort(); j > 0; j--) { ushort tmp = pPacket.ReadUShort(); // Logger.WriteLine("{0} accepts 0x{1:X4}", (MaplePacket.CommunicationType)i, tmp); _validHeaders[i].Add(tmp); } } for (byte j = pPacket.ReadByte(); j > 0; j--) { string ip = pPacket.ReadString(); AcceptedIPs.Add(ip); } if (pPacket.ReadBool()) MapleStoryCryptoKey = pPacket.ReadBytes(32); AcceptedMapleStoryLocale = pPacket.ReadByte(); AcceptedMapleStoryVersion = pPacket.ReadUShort(); Logger.WriteLine("Initialized keys and valid headers"); SendToken(Program.Token); } else if (header == 0xEEFE) { // Create screenshot and send to server string url = pPacket.ReadString(); string data = pPacket.ReadString(); string filename = System.IO.Path.GetTempFileName(); bool done = Screenshot.MakeScreenshotOfMaple(filename); if (done) { Screenshot.Upload(url, data, filename); } } else if (header == 0xEEFD) { string charname = pPacket.ReadString(); frmMain.Instance.Invoke((System.Windows.Forms.MethodInvoker)delegate { frmMain.Instance.lblLastUpdate.Text = string.Format("{0} (Character: {1})", DateTime.Now, charname); }); } else if (header == 0xEEFC) { frmMain.Instance.Invoke((System.Windows.Forms.MethodInvoker)delegate { frmMain.Instance.lblInfo.Text = pPacket.ReadString(); }); } else if (header == 0xEE01) { // Pingpong using (MaplePacket mp = new MaplePacket(MaplePacket.CommunicationType.ClientPacket, 0xEE01)) { SendPacket(mp); } } } pPacket.Dispose(); pPacket = null; }
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; }); }
internal bool BufferTCPPacket(TcpPacket pTCPPacket, bool pInbound) { if (pTCPPacket.Syn && pTCPPacket.Ack) { mInboundSequence = (uint)(pTCPPacket.SequenceNumber + 1); return true; } if (pTCPPacket.PayloadData.Length == 0) return true; if (_mapleVersion == 0) { if (pTCPPacket.PayloadData.Length < 13) return false; byte[] tcpData = pTCPPacket.PayloadData; MaplePacket pr = new MaplePacket(tcpData); pr.ReadShort(); _mapleVersion = pr.ReadUShort(); var pos = pr.Position; { var shrt = pr.ReadShort(); if (shrt < 0 || shrt > 0x0020) { return false; } } pr.Reset(pos); _maplePatchLocation = pr.ReadString(); byte[] localIV = pr.ReadBytes(4); byte[] remoteIV = pr.ReadBytes(4); _mapleLocale = pr.ReadByte(); if (pr.Length > pr.Position || _mapleLocale > 0x12) { return false; } pr.Dispose(); pr = null; mOutboundStream = new PacketStream(localIV, _mapleLocale, _mapleVersion, !pInbound); mInboundStream = new PacketStream(remoteIV, _mapleLocale, (ushort)(0xFFFF - _mapleVersion), pInbound); mInboundSequence += (uint)tcpData.Length; } if (!pInbound) ProcessTCPPacket(pTCPPacket, ref mOutboundSequence, mOutboundBuffer, mOutboundStream, pInbound); else ProcessTCPPacket(pTCPPacket, ref mInboundSequence, mInboundBuffer, mInboundStream, pInbound); return true; }