Example #1
0
        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;
                    }
                }
            }
        }
Example #2
0
        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);
                            }
                        }

                    }
                }
            });
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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;
            });
        }
Example #5
0
        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();
        }