예제 #1
0
        private void LoadDBConfig(string configFile)
        {
            var lines = File.ReadLines(configFile)
                        .Select(l => l.Split(' '))
                        .Select(p => p.Length == 2 ? "" : p[2])
                        .ToList();
            string Username = lines[0];
            string Password = lines[1];
            string Database = lines[2];
            string Host     = lines[3];

            CharacterDatabase = new MySQL_Connection(MasterThread.Instance, Username, Password, Database, Host);
            CharacterDBAccessor.InitializeDB(CharacterDatabase);
        }
예제 #2
0
        public override void AC_OnPacketInbound(Packet packet)
        {
            try
            {
                if (Server == null)
                {
                    switch ((ISClientMessages)packet.ReadByte())
                    {
                    case ISClientMessages.ServerRequestAllocation:
                    {
                        string      serverName = packet.ReadString();
                        LocalServer ls;
                        if (!CenterServer.Instance.LocalServers.TryGetValue(serverName, out ls))
                        {
                            Program.MainForm.LogAppend("Server doesn't exist in configuration: " + serverName + ". Disconnecting.");
                            Disconnect();
                            return;
                        }
                        var publicIp = System.Net.IPAddress.Parse(packet.ReadString());
                        var port     = packet.ReadUShort();

                        Program.MainForm.LogAppend(
                            $"Server connecting... Name: {serverName}, Public IP: {publicIp}, Port {port}");

                        if (ls.Type == LocalServerType.Game || ls.Type == LocalServerType.Shop)
                        {
                            byte worldid = packet.ReadByte();
                            if (World.ID != worldid)
                            {
                                Program.MainForm.LogAppend(
                                    $"{serverName} disconnected because it didn't have a valid world ID ({worldid})");
                                Disconnect();
                                return;
                            }
                        }


                        if (ls.Connected)
                        {
                            if (ls.InMaintenance)
                            {
                                Program.MainForm.LogAppend(
                                    $"Server is already connected: {serverName}, but already in maintenance. Disconnecting.");
                                Disconnect();
                                return;
                            }

                            Program.MainForm.LogAppend(
                                $"Server is already connected: {serverName}. Setting up transfer...");
                            ls.InMaintenance = true;
                        }

                        Server          = ls;
                        Server.PublicIP = publicIp;
                        Server.Port     = port;
                        Server.SetConnection(this);

                        Packet pw = new Packet(ISServerMessages.ServerAssignmentResult);
                        pw.WriteBool(Server.InMaintenance);

                        if (ls.Type == LocalServerType.Game || ls.Type == LocalServerType.Shop)
                        {
                            pw.WriteByte(Server.ChannelID);
                        }

                        if (Server.Type == LocalServerType.Game)
                        {
                            Program.MainForm.LogAppend(
                                $"Gameserver assigned! Name {serverName}; Channel ID {Server.ChannelID}");
                        }
                        else if (Server.Type == LocalServerType.Login)
                        {
                            Program.MainForm.LogAppend("Login connected.");
                        }
                        else if (Server.Type == LocalServerType.Shop)
                        {
                            Program.MainForm.LogAppend($"Shopserver assigned on idx {Server.ChannelID}");
                        }

                        SendPacket(pw);

                        SendRates();


                        break;
                    }
                    }
                }
                else
                {
                    var opcode = (ISClientMessages)packet.ReadByte();
                    switch (opcode)
                    {
                    case ISClientMessages.ServerMigrationUpdate:
                    {
                        if (!Server.InMaintenance)
                        {
                            Program.MainForm.LogAppend("Received ServerMigrationUpdate while not in maintenance!");
                            break;
                        }

                        var forwardPacket = new Packet(ISServerMessages.ServerMigrationUpdate);
                        forwardPacket.WriteBytes(packet.ReadLeftoverBytes());

                        // Figure out what way we need to send the packet
                        if (Server.Connection == this)
                        {
                            Server.TransferConnection.SendPacket(forwardPacket);
                        }
                        else
                        {
                            Server.Connection.SendPacket(forwardPacket);
                        }

                        break;
                    }

                    case ISClientMessages.ChangeRates:
                    {
                        Server.RateMobEXP     = packet.ReadDouble();
                        Server.RateMesoAmount = packet.ReadDouble();
                        Server.RateDropChance = packet.ReadDouble();
                        break;
                    }

                    case ISClientMessages.ServerSetConnectionsValue:
                    {
                        Server.Connections = packet.ReadInt();
                        break;
                    }

                    case ISClientMessages.PlayerChangeServer:
                    {
                        string hash    = packet.ReadString();
                        int    charid  = packet.ReadInt();
                        byte   world   = packet.ReadByte();
                        byte   channel = packet.ReadByte();
                        bool   CCing   = packet.ReadBool();

                        var chr = CenterServer.Instance.FindCharacter(charid);

                        Packet pw = new Packet(ISServerMessages.PlayerChangeServerResult);
                        pw.WriteString(hash);
                        pw.WriteInt(charid);

                        bool        found = true;
                        LocalServer ls    = null;
                        // this will null the key, so if there were two instances CCing,
                        // both would probably get killed.
                        if (RedisBackend.Instance.PlayerIsMigrating(charid, false))
                        {
                            Program.MainForm.LogAppend("Character {0} tried to CC while already CCing.", charid);
                            pw.WriteInt(0);
                            pw.WriteShort(0);
                            found = false;
                        }
                        else if (channel < 50 &&
                                 World.GameServers.TryGetValue(channel, out ls) &&
                                 ls.Connected)
                        {
                            pw.WriteBytes(ls.PublicIP.GetAddressBytes());
                            pw.WriteUShort(ls.Port);

                            RedisBackend.Instance.SetMigratingPlayer(charid);

                            if (chr != null)
                            {
                                chr.isCCing = true;
                            }

                            if (this.Server.Type == LocalServerType.Login)
                            {
                                CharacterDBAccessor.UpdateRank(charid);
                            }
                        }
                        else if (channel >= 50 &&
                                 World.ShopServers.TryGetValue((byte)(channel - 50), out ls) &&
                                 ls.Connected)
                        {
                            pw.WriteBytes(ls.PublicIP.GetAddressBytes());
                            pw.WriteUShort(ls.Port);

                            RedisBackend.Instance.SetMigratingPlayer(charid);

                            if (chr != null)
                            {
                                chr.isCCing     = true;
                                chr.LastChannel = chr.ChannelID;
                                chr.InCashShop  = true;
                            }
                        }
                        else
                        {
                            Program.MainForm.LogAppend("Character {0} tried to CC to channel that is not online.", charid);
                            pw.WriteInt(0);
                            pw.WriteShort(0);
                            found = false;
                        }


                        if (CCing && found && chr != null && ls != null)
                        {
                            chr.FriendsList.SaveBuddiesToDb();
                            chr.isConnectingFromLogin = false;

                            // Give the channel server some info from this server
                            var channelPacket = new Packet(ISServerMessages.PlayerChangeServerData);
                            channelPacket.WriteInt(charid);
                            channelPacket.WriteBytes(packet.ReadLeftoverBytes());

                            if (Server.ChannelID == channel &&
                                Server.InMaintenance)
                            {
                                // Server in maintenance...
                                ls.TransferConnection?.SendPacket(channelPacket);
                            }
                            else
                            {
                                // Changing channels, meh
                                ls.Connection?.SendPacket(channelPacket);
                            }
                        }

                        SendPacket(pw);
                        break;
                    }

                    case ISClientMessages.ServerRegisterUnregisterPlayer:     // Register/unregister character
                    {
                        int  charid = packet.ReadInt();
                        bool add    = packet.ReadBool();
                        if (add)
                        {
                            string charname  = packet.ReadString();
                            short  job       = packet.ReadShort();
                            byte   level     = packet.ReadByte();
                            byte   admin     = packet.ReadByte();
                            var    character = CenterServer.Instance.AddCharacter(charname, charid, Server.ChannelID, job, level, admin);

                            if (Party.Parties.TryGetValue(character.PartyID, out Party party))
                            {
                                party.SilentUpdate(character.ID);
                            }
                            else if (character.PartyID != 0)
                            {
                                Program.MainForm.LogAppend("Trying to register a character, but the party was not found??? PartyID: {0}, character ID {1}", character.PartyID, charid);
                                character.PartyID = 0;
                            }

                            var friendsList = character.FriendsList;
                            if (friendsList != null)
                            {
                                friendsList.OnOnlineCC(true, false);
                                friendsList.SendBuddyList();
                                friendsList.PollRequests();
                            }
                        }
                        else
                        {
                            bool ccing     = packet.ReadBool();
                            var  character = CenterServer.Instance.FindCharacter(charid);
                            if (ccing == false)
                            {
                                character.IsOnline = false;

                                if (Party.Parties.TryGetValue(character.PartyID, out Party party))
                                {
                                    if (party.leader.id == charid)
                                    {
                                        // Disband the party
                                        party.Leave(character);
                                    }
                                    else
                                    {
                                        party.SilentUpdate(character.ID);
                                    }
                                }

                                character.FriendsList?.OnOnlineCC(true, true);

                                // Fix this. When you log back in, the chat has 2 of you.
                                // Messenger.LeaveMessenger(character.ID);
                            }

                            if (Party.Invites.ContainsKey(character.ID))
                            {
                                Party.Invites.Remove(character.ID);
                            }
                        }

                        SendUserNoUpdateToLogins();

                        break;
                    }


                    case ISClientMessages.BroadcastPacketToGameservers:
                    {
                        var p = new Packet(packet.ReadLeftoverBytes());
                        World.SendPacketToEveryGameserver(p);
                        break;
                    }

                    case ISClientMessages.BroadcastPacketToShopservers:
                    {
                        var p = new Packet(packet.ReadLeftoverBytes());
                        World.SendPacketToEveryShopserver(p);
                        break;
                    }

                    default:
                        switch (Server.Type)
                        {
                        case LocalServerType.Game: HandleGamePacket(opcode, packet); break;

                        case LocalServerType.Login: HandleLoginPacket(opcode, packet); break;

                        case LocalServerType.Shop: HandleShopPacket(opcode, packet); break;
                        }

                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Program.LogFile.WriteLine("Exception Caught:\r\n{0}", ex.ToString());
                //FileWriter.WriteLine(@"etclog\ExceptionCatcher.log", "[Center Server][" + DateTime.Now.ToString() + "] Exception caught: " + ex.Message + Environment.NewLine + Environment.NewLine + "Stacktrace: " + ex.StackTrace, true);
                //Disconnect();
            }
        }
예제 #3
0
        private void HandleLoginPacket(ISClientMessages opcode, Packet packet)
        {
            switch (opcode)
            {
            case ISClientMessages.PlayerRequestWorldLoad:
            {
                string hash  = packet.ReadString();
                byte   world = packet.ReadByte();

                Packet pw = new Packet(ISServerMessages.PlayerRequestWorldLoadResult);
                pw.WriteString(hash);

                if (World.ID == world)
                {
                    World.AddWarning(pw);
                }
                else
                {
                    pw.WriteByte(2);         // full load
                }

                SendPacket(pw);
                break;
            }

            case ISClientMessages.PlayerRequestChannelStatus:     // channel online check
            {
                string hash      = packet.ReadString();
                byte   world     = packet.ReadByte();
                byte   channel   = packet.ReadByte();
                int    accountId = packet.ReadInt();

                Packet pw = new Packet(ISServerMessages.PlayerRequestChannelStatusResult);
                pw.WriteString(hash);

                if (World.ID != world ||
                    World.GameServers.TryGetValue(channel, out LocalServer ls) == false ||
                    ls.InMaintenance ||
                    !ls.Connected)
                {
                    pw.WriteByte(0x09);         // Channel Offline
                }
                else
                {
                    pw.WriteByte(0);
                    pw.WriteByte(channel);

                    try
                    {
                        var ids = CharacterDBAccessor.GetCharacterIdList(accountId).ToList();
                        pw.WriteByte((byte)ids.Count);

                        foreach (var id in ids)
                        {
                            var ad      = CharacterDBAccessor.LoadAvatar(id);
                            var ranking = CharacterDBAccessor.LoadRank(id);

                            ad.Encode(pw);
                            pw.WriteBool(ranking != null);
                            if (ranking != null)
                            {
                                var(worldRank, worldRankMove, jobRank, jobRankMove) = ranking.Value;
                                pw.WriteInt(worldRank);
                                pw.WriteInt(worldRankMove);
                                pw.WriteInt(jobRank);
                                pw.WriteInt(jobRankMove);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Program.MainForm.LogAppend("Error while building packet for characterselect! {0}", ex);
                        _log.Error(ex);
                        pw = new Packet(ISServerMessages.PlayerRequestChannelStatusResult);
                        pw.WriteString(hash);
                        pw.WriteByte(1);
                    }
                }

                SendPacket(pw);
                break;
            }

            case ISClientMessages.PlayerDeleteCharacter:
            {
                string hash      = packet.ReadString();
                int    accountId = packet.ReadInt();
                int    charId    = packet.ReadInt();

                var p = new Packet(ISServerMessages.PlayerDeleteCharacterResult);
                p.WriteString(hash);
                p.WriteInt(charId);
                try
                {
                    var deleteCharacterResult = CharacterDBAccessor.DeleteCharacter(accountId, charId);
                    p.WriteByte(deleteCharacterResult);

                    if (deleteCharacterResult == 0)
                    {
                        var foundChar = CenterServer.Instance.FindCharacter(charId, false);
                        if (foundChar != null)
                        {
                            if (foundChar.PartyID != 0 &&
                                Party.Parties.TryGetValue(foundChar.PartyID, out Party party))
                            {
                                party.Leave(foundChar);
                            }

                            // Registered, so get rid of it
                            CenterServer.Instance.CharacterStore.Remove(foundChar);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                    Program.MainForm.LogAppend("Error while deleting character! {0}", ex);
                    p.WriteByte(10);
                }
                SendPacket(p);
                break;
            }

            case ISClientMessages.PlayerCreateCharacterNamecheck:
            {
                string hash     = packet.ReadString();
                string charname = packet.ReadString();

                var p = new Packet(ISServerMessages.PlayerCreateCharacterNamecheckResult);
                p.WriteString(hash);
                p.WriteString(charname);
                try
                {
                    p.WriteBool(CharacterDBAccessor.CheckDuplicateID(charname));
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                    Program.MainForm.LogAppend("Error while checking for duplicate ID! {0}", ex);
                    p.WriteBool(true);
                }

                SendPacket(p);
                break;
            }

            case ISClientMessages.PlayerCreateCharacter:
            {
                string hash      = packet.ReadString();
                int    accountId = packet.ReadInt();
                byte   gender    = packet.ReadByte();

                string charname = packet.ReadString();

                int face      = packet.ReadInt();
                int hair      = packet.ReadInt();
                int haircolor = packet.ReadInt();
                int skin      = packet.ReadInt();

                int top    = packet.ReadInt();
                int bottom = packet.ReadInt();
                int shoes  = packet.ReadInt();
                int weapon = packet.ReadInt();

                byte str  = packet.ReadByte();
                byte dex  = packet.ReadByte();
                byte intt = packet.ReadByte();
                byte luk  = packet.ReadByte();

                var p = new Packet(ISServerMessages.PlayerCreateCharacterResult);
                p.WriteString(hash);

                try
                {
                    if (CharacterDBAccessor.CheckDuplicateID(charname))
                    {
                        p.WriteBool(false);
                    }
                    else
                    {
                        int id = CharacterDBAccessor.CreateNewCharacter(
                            accountId,
                            charname,
                            gender,

                            face, hair, haircolor, skin,
                            str, dex, intt, luk,
                            top, bottom, shoes, weapon
                            );

                        var ad = CharacterDBAccessor.LoadAvatar(id);

                        p.WriteBool(true);

                        ad.Encode(p);
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                    Program.MainForm.LogAppend("Error while creating character! {0}", ex);

                    p = new Packet(ISServerMessages.PlayerCreateCharacterResult);
                    p.WriteString(hash);
                    p.WriteBool(false);
                }

                SendPacket(p);

                break;
            }
            }
        }