public bool AssertForHack(bool isHack, string hackType, bool seriousHack = true)
        {
            if (!isHack || IsAdmin) return false;

            HackLog.Warn(hackType);
            Trace.WriteLine(hackType);

            if (IsGM || IsAdmin) return false;
            HackLog.Warn(hackType);
            if (seriousHack && HacklogMuted < MasterThread.CurrentDate)
            {
                MessagePacket.SendNoticeGMs(
                    $"Check '{hackType}' triggered! Character: '{Name}', Map: '{MapID}'.",
                    MessagePacket.MessageTypes.Megaphone
                );
            }

            return isHack;
        }
Exemplo n.º 2
0
        public override void OnHackDetected()
        {
            if (!Loaded || !HackDetected.HasValue)
            {
                return;
            }
            var character = Player.Character;
            var hack      = HackDetected.Value;

            if (hack.HasFlag(RedisBackend.HackKind.Speedhack))
            {
                MessagePacket.SendNoticeGMs(
                    $"Detected speed hacks on character '{character.Name}', map {character.MapID}...",
                    MessagePacket.MessageTypes.RedText);

                if (character.IsGM == false)
                {
                    character.PermaBan(
                        "Detected speedhack",
                        extraDelay: (int)((2 * 60) + Rand32.Next() % (5 * 60))
                        );
                }
            }

            if (hack.HasFlag(RedisBackend.HackKind.MemoryEdits))
            {
                MessagePacket.SendNoticeGMs(
                    $"Detected memory edits on character '{character.Name}', map {character.MapID}.",
                    MessagePacket.MessageTypes.RedText
                    );

                if (character.IsGM == false)
                {
                    // Add some randomness
                    character.PermaBan(
                        "Detected memory edits",
                        // Between 2 and 12 minutes
                        extraDelay: (int)((2 * 60) + Rand32.Next() % (10 * 60))
                        );
                }
            }
        }
Exemplo n.º 3
0
        public static void HandleAdminCommandMessage(Character chr, Packet packet)
        {
            byte   to          = packet.ReadByte();
            byte   TypeMessage = packet.ReadByte(); //   /alert, /notice, /slide
            string Message     = packet.ReadString();

            switch (to)
            {
            case 0x00:     //To every game server
                MessagePacket.SendAdminMessage(chr, Message, TypeMessage, 0);
                break;

            case 0x01:     //To channel
                MessagePacket.SendAdminMessage(chr, Message, TypeMessage, 1);
                break;

            case 0x02:     //To map
                MessagePacket.SendAdminMessage(chr, Message, TypeMessage, 2);
                break;
            }
        }
Exemplo n.º 4
0
        public static void HandlePacket(Character pCharacter, Packet pPacket)
        {
            //MessagePacket.SendNotice("PACKET: " + pPacket.ToString(), pCharacter);
            byte Type = pPacket.ReadByte();

            switch (Type)
            {
            case 0:     // Create miniroom
            {
                if (pCharacter.AssertForHack(!pCharacter.CanAttachAdditionalProcess, "Trying to create a miniroom while he cannot attach additional process."))
                {
                    return;
                }
                CreateMiniRoomBase(pCharacter, pPacket);
                break;
            }

            case 2:     // Invite To miniroom
            {
                if (pCharacter.Room == null)
                {
                    InviteResult(pCharacter, 1);
                    return;         // NOT OPENED OR FULL
                }

                int       playerid = pPacket.ReadInt();
                Character victim   = pCharacter.Field.GetPlayer(playerid);

                if (victim == null)
                {
                    miniroomLog.Info($"{pCharacter.Name} fails to invite charid {playerid}: not found?");
                    // Not found!
                    InviteResult(pCharacter, 1);
                }
                else if (pCharacter.Room.IsFull())
                {
                    miniroomLog.Info($"{pCharacter.Name} fails to invite charid {playerid}: room already full?");
                    InviteResult(pCharacter, 2, victim.Name);         // DEM REAL DEAL
                }
                else if ((pCharacter.IsGM == false && victim.IsGM) ||
                         (pCharacter.IsGM && victim.IsGM == false))
                {
                    miniroomLog.Info($"{pCharacter.Name} fails to invite charid {playerid}: non-admin tried to invite admin or vice versa");

                    InviteResult(pCharacter, 1);
                }
                else
                {
                    miniroomLog.Info($"{pCharacter.Name} invited {victim.Name} (charid {playerid})");
                    Invite(pCharacter.Room, pCharacter, victim);
                }

                break;
            }

            case 3:     // Decline Invite
            {
                int roomid = pPacket.ReadInt();

                miniroomLog.Info($"{pCharacter.Name} declined invite.");
                if (!MiniRoomBase.MiniRooms.ContainsKey(roomid))
                {
                    // REPORT
                    //ReportManager.FileNewReport("Tried opening a trade room without a proper ID.", pCharacter.ID, 0);
                    //MessagePacket.SendNotice("Tried opening a trade room without a proper ID. ID was: " + roomid.ToString(), pCharacter);
                    return;
                }

                MiniRoomBase mrb = MiniRoomBase.MiniRooms[roomid];
                //if (mrb.IsFull())
                //{

                //}
                break;
            }

            case 4:     // Enter Room
            {
                EnterMiniRoom(pCharacter, pPacket);
                break;
            }

            case 0x06:     // Chat
            {
                if (pCharacter.Room == null)
                {
                    return;
                }

                var text = pPacket.ReadString();

                var chatLogLine = pCharacter.Name + ": " + text;
                if (MessagePacket.ShowMuteMessage(pCharacter))
                {
                    miniroomChatLog.Info("[MUTED] " + chatLogLine);
                }
                else
                {
                    miniroomChatLog.Info(chatLogLine);
                    Chat(pCharacter.Room, pCharacter, text, -1);
                }

                break;
            }

            case 0x12:     //Add item to Player Shop
            {
                if (pCharacter.Room == null)
                {
                    return;
                }

                byte  inventory       = pPacket.ReadByte();
                short inventoryslot   = pPacket.ReadShort();
                short bundleamount    = pPacket.ReadShort();
                short AmountPerBundle = pPacket.ReadShort();
                int   price           = pPacket.ReadInt();
                PlayerShop.HandleShopUpdateItem(pCharacter, inventory, inventoryslot, bundleamount, AmountPerBundle, price);
                break;
            }

            case 0x13:     //Buy item from shop
            {
                if (pCharacter.Room == null)
                {
                    return;
                }

                byte       slot         = pPacket.ReadByte();
                short      bundleamount = pPacket.ReadShort();
                PlayerShop ps           = MiniRoomBase.PlayerShops[pCharacter.Room.ID];

                if (ps != null)
                {
                    ps.BuyItem(pCharacter, slot, bundleamount);
                }

                break;
            }

            case 0xA:     //Leave
            {
                MiniRoomBase mr = pCharacter.Room;
                if (mr == null)
                {
                    return;
                }

                miniroomLog.Info($"{pCharacter.Name} declined invite.");

                if (mr.Type == MiniRoomBase.RoomType.Trade)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        Character chr    = mr.Users[i];
                        Character leader = mr.Users[0];

                        if (chr == null)
                        {
                            continue;
                        }

                        mr.RemovePlayer(chr, 1);
                        //mr.Users[i] = null; //send this after all characters are removed
                    }
                }

                else if (mr.Type == MiniRoomBase.RoomType.PersonalShop)
                {
                    mr.RemovePlayerFromShop(pCharacter);
                }

                else if (mr.Type == MiniRoomBase.RoomType.Omok)
                {
                    //MessagePacket.SendNotice("leave omok", pCharacter);
                    Omok omok = MiniRoomBase.Omoks[pCharacter.Room.ID];

                    if (pCharacter == omok.Users[0])
                    {
                        omok.CloseOmok(pCharacter);
                    }
                    else
                    {
                        ShowLeaveRoom(pCharacter.Room, pCharacter, 2);
                        omok.RemovePlayer(pCharacter, 1);
                    }
                }

                break;
            }

            case 0xB:     //Add announce box
            {
                if (pCharacter.Room == null)
                {
                    return;
                }
                MiniGamePacket.AddAnnounceBox(pCharacter, (byte)pCharacter.Room.Type, pCharacter.Room.ID, pCharacter.Room.Title, pCharacter.Room.Private, 0, false);
                byte RoomType = (byte)pCharacter.Room.Type;

                switch (RoomType)
                {
                case 1:
                {
                    pCharacter.Field.Omoks.Add(pCharacter.Room.ID, MiniRoomBase.Omoks[pCharacter.Room.ID]);
                    break;
                }

                case 4:
                {
                    pCharacter.Field.PlayerShops.Add(pCharacter.Room.ID, MiniRoomBase.PlayerShops[pCharacter.Room.ID]);
                    break;
                }
                }
                break;
            }

            case 0x17:     //Move Item from player shop to inventory
            {
                return;

                if (pCharacter.AssertForHack(!(pCharacter.Room is PlayerShop), "PlayerShop hack: taking back item while not in playershop"))
                {
                    return;
                }
                byte       slot = pPacket.ReadByte();   //reads as byte, sends as short... wtf lol
                PlayerShop ps   = pCharacter.Room as PlayerShop;
                if (pCharacter.AssertForHack(ps.Owner != pCharacter, "PlayerShop hack: taking back item while not owner"))
                {
                    return;
                }

                ps.HandleMoveItemBack(pCharacter, slot);
                ps.Items.Remove(slot);
                break;
            }

            case 0x19:     //Request tie result
            {
                bool result = pPacket.ReadBool();
                break;
            }

            case 0x20:     //Ready
            {
                MiniGamePacket.Ready(pCharacter, pCharacter.Room);
                break;
            }

            case 0x21:
            {
                MiniGamePacket.UnReady(pCharacter, pCharacter.Room);
                break;
            }

            case 0x22:     //Expell user
            {
                //Todo : expell
                break;
            }

            case 0x23:
            {
                Omok omok = MiniRoomBase.Omoks[pCharacter.Room.ID];
                if (omok != null)
                {
                    MiniGamePacket.Start(pCharacter, pCharacter.Room);
                    omok.GameStarted = true;
                }
                break;
            }

            case 0x25:
            {
                Omok omok = MiniRoomBase.Omoks[pCharacter.Room.ID];
                omok.UpdateGame(pCharacter);
                omok.GameStarted = false;
                break;
            }

            case 0x26:     //Place omok piece
            {
                Omok omok = MiniRoomBase.Omoks[pCharacter.Room.ID];

                if (omok != null)
                {
                    int  X     = pPacket.ReadInt();
                    int  Y     = pPacket.ReadInt();
                    byte Piece = pPacket.ReadByte();

                    if (omok.Stones[X, Y] != Piece && omok.Stones[X, Y] != omok.GetOtherPiece(Piece))
                    {
                        MiniGamePacket.MoveOmokPiece(pCharacter, pCharacter.Room, X, Y, Piece);
                        omok.AddStone(X, Y, Piece, pCharacter);
                    }
                    else
                    {
                        MiniGamePacket.OmokMessage(pCharacter, pCharacter.Room, 0);
                    }
                    //MessagePacket.SendNotice("X : " + X + " Y : " + Y, pCharacter);
                    if (omok.CheckStone(Piece))
                    {
                        //MessagePacket.SendNotice("Win!", pCharacter);
                        omok.UpdateGame(pCharacter);
                        Piece            = 0xFF;
                        omok.GameStarted = false;
                    }
                }

                break;
            }

            case 0x1C:
            {
                for (int i = 0; i < 2; i++)
                {
                    if (pCharacter.Room.Users[i] != pCharacter)
                    {
                        MiniGamePacket.RequestHandicap(pCharacter.Room.Users[i], pCharacter.Room);
                    }
                }

                break;
            }

            case 0x1D:     //Request handicap result
            {
                bool result = pPacket.ReadBool();
                Omok omok   = MiniRoomBase.Omoks[pCharacter.Room.ID];

                if (omok != null)
                {
                    if (result == true)
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            if (pCharacter.Room.Users[i] != pCharacter)
                            {
                                if (omok.PlacedStone[i] == false)
                                {
                                    MiniGamePacket.RequestHandicapResult(pCharacter, pCharacter.Room, result, 2);
                                    omok.TotalStones -= 2;
                                    //MessagePacket.SendNotice("removed", pCharacter);
                                }
                                else
                                {
                                    MiniGamePacket.RequestHandicapResult(pCharacter, pCharacter.Room, result, 1);
                                    omok.TotalStones--;
                                    //omok.Stones[omok.LastPlacedStone[(byte)(pCharacter.RoomSlotId + 1)].mX, omok.LastPlacedStone[(byte)(pCharacter.RoomSlotId + 1)].mY] = 0xFF;
                                    //MessagePacket.SendNotice("Removed stone", pCharacter);
                                }
                            }
                        }
                    }
                }
                break;
            }

            default:
            {
                if (pCharacter.Room != null)
                {
                    pCharacter.Room.OnPacket(pCharacter, Type, pPacket);
                }
                //MessagePacket.SendNotice("This feature is currently disabled due to maintenance.", pCharacter);
                break;
            }
            }
        }
Exemplo n.º 5
0
        public bool TryHandlePlayerPacket(Packet packet, ISServerMessages msg)
        {
            switch (msg)
            {
            case ISServerMessages.PlayerChangeServerResult:
            {
                string session = packet.ReadString();
                Player player  = Server.Instance.GetPlayer(session);
                if (player != null)
                {
                    player.Socket.StartLogging();
                    int    charid = packet.ReadInt();
                    byte[] ip     = packet.ReadBytes(4);
                    ushort port   = packet.ReadUShort();
                    if (port == 0)
                    {
                        Packet pw = new Packet(ServerMessages.TRANSFER_CHANNEL_REQ_IGNORED);
                        player.Character.SendPacket(pw);
                    }
                    else
                    {
                        player.Character.CleanupInstances();
                        RedisBackend.Instance.SetPlayerCCIsBeingProcessed(charid);

                        player.IsCC = true;
                        player.Socket.SendConnectToServer(ip, port);
                    }
                }
                else
                {
                    Program.MainForm.LogAppend("Tried to CC unknown player (unknown hash)");
                }

                break;
            }

            case ISServerMessages.PlayerWhisperOrFindOperationResult:
            {
                bool      whisper    = packet.ReadBool();
                bool      found      = packet.ReadBool();
                int       victim     = packet.ReadInt();
                Character victimChar = Server.Instance.GetCharacter(victim);
                if (victimChar == null)
                {
                    break;
                }
                victimChar.Player.Socket.StartLogging();

                if (whisper)
                {
                    if (found)
                    {
                        string sender        = packet.ReadString();
                        byte   channel       = packet.ReadByte();
                        string message       = packet.ReadString();
                        bool   direction     = packet.ReadBool();
                        byte   directionByte = 18;
                        if (direction)
                        {
                            directionByte = 10;
                        }
                        MessagePacket.Whisper(victimChar, sender, channel, message, directionByte);
                    }
                    else
                    {
                        string sender = packet.ReadString();
                        MessagePacket.Find(victimChar, sender, -1, 0, false);
                    }
                }
                else
                {
                    if (found)
                    {
                        string sender  = packet.ReadString();
                        sbyte  channel = packet.ReadSByte();
                        sbyte  wat     = packet.ReadSByte();
                        MessagePacket.Find(victimChar, sender, channel, wat, false);
                    }
                    else
                    {
                        string sender = packet.ReadString();
                        MessagePacket.Find(victimChar, sender, -1, 0, false);
                    }
                }
                break;
            }

            case ISServerMessages.PlayerSuperMegaphone:
            {
                MessagePacket.SendSuperMegaphoneMessage(packet.ReadString(), packet.ReadBool(), packet.ReadByte());
                break;
            }

            case ISServerMessages.AdminMessage:
            {
                string message = packet.ReadString();
                byte   type    = packet.ReadByte();

                Packet pw = new Packet(ServerMessages.BROADCAST_MSG);
                pw.WriteByte(type);
                pw.WriteString(message);
                if (type == 4)
                {
                    pw.WriteBool(message.Length != 0);
                }

                foreach (var kvp in DataProvider.Maps)
                {
                    kvp.Value.SendPacket(pw);
                }
                break;
            }

            case ISServerMessages.PlayerChangeServerData:
            {
                var charid           = packet.ReadInt();
                var readBufferPacket = new Packet(packet.ReadLeftoverBytes());
                Server.Instance.CCIngPlayerList[charid] = new Tuple <Packet, long>(readBufferPacket, MasterThread.CurrentTime);
                break;
            }

            case ISServerMessages.KickPlayerResult:
            {
                int    userId = packet.ReadInt();
                Player player = Server.Instance.PlayerList.Values.FirstOrDefault(p => p.Character != null && p.Character.UserID == userId);
                if (player != null)
                {
                    Program.MainForm.LogAppend("Handling centerserver kick request for user " + userId);
                    player.Socket.Disconnect();
                }
                break;
            }

            case ISServerMessages.PlayerSendPacket:
            {
                Character pChar = Server.Instance.GetCharacter(packet.ReadInt());
                ////Console.WriteLine(pChar.Name);
                pChar?.SendPacket(packet.ReadLeftoverBytes());
                break;
            }

            default: return(false);
            }
            return(true);
        }
Exemplo n.º 6
0
        public void OnPlayerLoad(Packet packet)
        {
            var characterId = packet.ReadInt();

            ThreadContext.Properties["CharacterID"] = characterId;

            if (RedisBackend.Instance.HoldoffPlayerConnection(characterId))
            {
                Program.MainForm.LogAppend("Bouncing charid: " + characterId);
                SendConnectToServer(Server.Instance.PublicIP.GetAddressBytes(), Server.Instance.Port, true);
                return;
            }


            if (RedisBackend.Instance.PlayerIsMigrating(characterId, true) == false)
            {
                var msg = "Disconnecting because not migrating. Charid: " + characterId;
                Server.Instance.ServerTraceDiscordReporter.Enqueue(msg);
                Program.MainForm.LogAppend(msg);
                goto cleanup_and_disconnect;
            }


            var uId = Server.Instance.CharacterDatabase.UserIDByCharID(characterId);

            ThreadContext.Properties["UserID"] = uId;
            if (Server.Instance.CharacterDatabase.IsBanned(uId))
            {
                var msg = "Disconnecting because banned. Charid: " + characterId + ". Userid: " + uId;
                Server.Instance.ServerTraceDiscordReporter.Enqueue(msg);
                Program.MainForm.LogAppend(msg);
                goto cleanup_and_disconnect;
            }

            if (Server.Instance.CharacterDatabase.IsIpBanned(IP))
            {
                var msg = "Disconnecting because IP banned. Charid: " + characterId + ". Userid: " + uId + ". IP: " + IP;
                Server.Instance.ServerTraceDiscordReporter.Enqueue(msg);
                Program.MainForm.LogAppend(msg);
                goto cleanup_and_disconnect;
            }

            if (Server.Instance.CharacterList.ContainsKey(characterId))
            {
                var msg = "Disconnecting characterId " + characterId + " from IP " + IP + ". Already connected in this channel.";
                Server.Instance.ServerTraceDiscordReporter.Enqueue(msg);
                Program.MainForm.LogAppend(msg);
                goto cleanup_and_disconnect;
            }

            var character  = new Character(characterId);
            var loadResult = character.Load(IP);

            if (loadResult != Character.LoadFailReasons.None)
            {
                var msg = "Disconnected characterId " + characterId + " from IP " + IP + ". " + loadResult;
                Server.Instance.ServerTraceDiscordReporter.Enqueue(msg);
                Program.MainForm.LogAppend(msg);
                goto cleanup_and_disconnect;
            }

            Player.Character = character;
            character.Player = Player;

            StartLogging();

            Program.MainForm.LogAppend(character.Name + " connected from IP " + IP + ".");

            Program.MainForm.ChangeLoad(true);
            Server.Instance.CharacterList.Add(characterId, character);
            if (character.IsGM)
            {
                Server.Instance.StaffCharacters.Add(character);
            }
            Loaded = true;

            //have to load summons after he joins the map, so i have moved this from the load method -Exile
            if (Server.Instance.CCIngPlayerList.TryGetValue(character.ID, out var info))
            {
                Server.Instance.CCIngPlayerList.Remove(character.ID);
            }

            var ccPacket = info?.Item1;

            if (ccPacket != null)
            {
                character.PrimaryStats.DecodeForCC(ccPacket);
            }

            character.PrimaryStats.CheckHPMP();

            MapPacket.SendJoinGame(character);

            if (character.IsGM)
            {
                string glevel = character.GMLevel == 1 ? "(GM Intern)" : character.GMLevel == 2 ? "(GM)" : "(Admin)";
                MessagePacket.SendNotice("Your GM Level: " + character.GMLevel + " " + glevel + ". Undercover? " + (character.Undercover ? "Yes" : "No"), character);
            }

            if (character.IsGM && !character.Undercover)
            {
                character.TryActivateHide();
            }

            character.Field.AddPlayer(character);

            if (ccPacket != null)
            {
                character.Summons.DecodeForCC(ccPacket);
            }

            MessagePacket.SendText(MessagePacket.MessageTypes.Header, Server.Instance.ScrollingHeader, character, MessagePacket.MessageMode.ToPlayer);

            Server.Instance.CenterConnection.RegisterCharacter(character.ID, character.Name, character.PrimaryStats.Job, character.PrimaryStats.Level, character.GMLevel);

            Server.Instance.CenterConnection.RequestBuddyListLoad(character.Name, false, character.PrimaryStats.BuddyListCapacity); //Sends a packet that request the buddylistload from the centerserver
            character.IsOnline = true;
            Server.Instance.CenterConnection.PlayerUpdateMap(character);

            // Just to be sure, check if he was banned

            if (RedisBackend.Instance.TryGetNonGameHackDetect(Player.Character.UserID, out var hax))
            {
                HackDetected = hax;
                OnHackDetected();
            }
            else if (HackDetected.HasValue)
            {
                OnHackDetected();
            }

            return;


cleanup_and_disconnect:

            Server.Instance.CCIngPlayerList.Remove(characterId);
            Disconnect();
        }
Exemplo n.º 7
0
        public override void AC_OnPacketInbound(Packet packet)
        {
            ClientMessages header = 0;

            try
            {
                header = (ClientMessages)packet.ReadByte();

                if (!Loaded || Player?.Character == null)
                {
                    switch (header)
                    {
                    case ClientMessages.MIGRATE_IN:
                        OnPlayerLoad(packet);
                        break;     //updated
                    }
                }
                // Block packets as we are migrating
                else if (Server.Instance.InMigration == false || Server.Instance.IsNewServerInMigration)
                {
                    var character = Player.Character;

                    if (logPackets.Contains(header))
                    {
                        PacketLog.ReceivedPacket(packet, (byte)header, Server.Instance.Name, IP);
                    }

                    switch (header)
                    {
                    case ClientMessages.ENTER_PORTAL:
                        MapPacket.OnEnterPortal(packet, character);
                        break;

                    case ClientMessages.CHANGE_CHANNEL:
                        OnChangeChannel(character, packet);
                        break;

                    case ClientMessages.ENTER_CASH_SHOP:
                        OnEnterCashShop(character);
                        break;

                    case ClientMessages.MOVE_PLAYER:
                        MapPacket.HandleMove(character, packet);
                        break;

                    case ClientMessages.SIT_REQUEST:
                        MapPacket.HandleSitChair(character, packet);
                        break;

                    case ClientMessages.ENTER_TOWN_PORTAL:
                        MapPacket.HandleDoorUse(character, packet);
                        break;

                    case ClientMessages.CLOSE_RANGE_ATTACK:
                        AttackPacket.HandleMeleeAttack(character, packet);
                        break;

                    case ClientMessages.RANGED_ATTACK:
                        AttackPacket.HandleRangedAttack(character, packet);
                        break;

                    case ClientMessages.MAGIC_ATTACK:
                        AttackPacket.HandleMagicAttack(character, packet);
                        break;

                    case ClientMessages.TAKE_DAMAGE:
                        CharacterStatsPacket.HandleCharacterDamage(character, packet);
                        break;

                    case ClientMessages.CHAT:
                        MessagePacket.HandleChat(character, packet);
                        break;

                    case ClientMessages.GROUP_MESSAGE:
                        MessagePacket.HandleSpecialChat(character, packet);
                        break;

                    case ClientMessages.WHISPER:
                        MessagePacket.HandleCommand(character, packet);
                        break;

                    case ClientMessages.EMOTE:
                        MapPacket.SendEmotion(character, packet.ReadInt());
                        break;

                    case ClientMessages.NPC_TALK:
                        MapPacket.HandleNPCChat(character, packet);
                        break;

                    case ClientMessages.NPC_TALK_MORE:
                        NpcPacket.HandleNPCChat(character, packet);
                        break;

                    case ClientMessages.SHOP_ACTION:
                        NpcPacket.HandleNPCShop(character, packet);
                        break;

                    case ClientMessages.STORAGE_ACTION:
                        StoragePacket.HandleStorage(character, packet);
                        break;

                    case ClientMessages.ITEM_MOVE:
                        InventoryPacket.HandleInventoryPacket(character, packet);
                        break;

                    case ClientMessages.ITEM_USE:
                        InventoryPacket.HandleUseItemPacket(character, packet);
                        break;

                    case ClientMessages.SUMMON_BAG_USE:
                        InventoryPacket.HandleUseSummonSack(character, packet);
                        break;

                    case ClientMessages.CASH_ITEM_USE:
                        CashPacket.HandleCashItem(character, packet);
                        break;

                    case ClientMessages.RETURN_SCROLL_USE:
                        InventoryPacket.HandleUseReturnScroll(character, packet);
                        break;

                    case ClientMessages.SCROLL_USE:
                        InventoryPacket.HandleScrollItem(character, packet);
                        break;

                    case ClientMessages.DISTRIBUTE_AP:
                        CharacterStatsPacket.HandleStats(character, packet);
                        break;

                    case ClientMessages.HEAL_OVER_TIME:
                        CharacterStatsPacket.HandleHeal(character, packet);
                        break;

                    case ClientMessages.DISTRIBUTE_SP:
                        SkillPacket.HandleAddSkillLevel(character, packet);
                        break;

                    case ClientMessages.PREPARE_SKILL:
                        SkillPacket.HandlePrepareSkill(character, packet);
                        break;

                    case ClientMessages.GIVE_BUFF:
                        SkillPacket.HandleUseSkill(character, packet);
                        break;

                    case ClientMessages.CANCEL_BUFF:
                        SkillPacket.HandleStopSkill(character, packet);
                        break;

                    case ClientMessages.DROP_MESOS:
                        DropPacket.HandleDropMesos(character, packet.ReadInt());
                        break;

                    case ClientMessages.GIVE_FAME:
                        FamePacket.HandleFame(character, packet);
                        break;

                    case ClientMessages.CHAR_INFO_REQUEST:
                        MapPacket.SendPlayerInfo(character, packet);
                        break;

                    case ClientMessages.SPAWN_PET:
                        PetsPacket.HandleSpawnPet(character, packet.ReadShort());
                        break;

                    case ClientMessages.SUMMON_MOVE:
                        MapPacket.HandleSummonMove(character, packet);
                        break;

                    case ClientMessages.SUMMON_ATTACK:
                        AttackPacket.HandleSummonAttack(character, packet);
                        break;

                    case ClientMessages.SUMMON_DAMAGED:
                        MapPacket.HandleSummonDamage(character, packet);
                        break;

                    case ClientMessages.MOB_MOVE:
                        MobPacket.HandleMobControl(character, packet);
                        break;

                    case ClientMessages.NPC_ANIMATE:
                        MapPacket.HandleNPCAnimation(character, packet);
                        break;

                    case ClientMessages.PET_MOVE: PetsPacket.HandleMovePet(character, packet); break;

                    case ClientMessages.PET_INTERACTION: PetsPacket.HandleInteraction(character, packet); break;

                    case ClientMessages.PET_ACTION: PetsPacket.HandlePetAction(character, packet); break;

                    case ClientMessages.FIELD_CONTIMOVE_STATE:
                        MapPacket.OnContiMoveState(character, packet);
                        break;

                    case ClientMessages.DROP_PICK_UP:
                        DropPacket.HandlePickupDrop(character, packet);
                        break;

                    case ClientMessages.MESSENGER:
                        MessengerHandler.HandleMessenger(character, packet);
                        break;

                    case ClientMessages.MINI_ROOM_OPERATION:
                        MiniRoomPacket.HandlePacket(character, packet);
                        break;

                    case ClientMessages.FRIEND_OPERATION:
                        BuddyHandler.HandleBuddy(character, packet);
                        break;

                    case ClientMessages.PARTY_OPERATION:
                        PartyHandler.HandleParty(character, packet);
                        break;

                    case ClientMessages.DENY_PARTY_REQUEST:
                        PartyHandler.HandleDecline(character, packet);
                        break;

                    case ClientMessages.REACTOR_HIT:
                        ReactorPacket.HandleReactorHit(character, packet);
                        break;

                    case ClientMessages.REPORT_USER:
                        MiscPacket.ReportPlayer(character, packet);
                        break;


                    //this is a garbage opcode that i use when doing janky client packet workarounds. This is where packets go to die.
                    case ClientMessages.JUNK:
                        Program.MainForm.LogDebug("received junk packet");
                        break;

                    // eh.. ignore?
                    // Happens when one of the following buffs are set:
                    // Stun, Poison, Seal, Darkness, Weakness, Curse
                    // Maybe patch out of the client
                    case ClientMessages.CHARACTER_IS_DEBUFFED: break;

                    // TODO: Implement???
                    case ClientMessages.MOB_APPLY_CONTROL: break;

                    case ClientMessages.CLIENT_HASH: break;

                    case ClientMessages.PONG:
                        // Make sure we update the player online thing
                        RedisBackend.Instance.SetPlayerOnline(
                            character.UserID,
                            Server.Instance.GetOnlineId()
                            );

                        // Cleanup expired items
                        character.Inventory.CheckExpired();
                        break;

                    default:
                        if (character.Field.HandlePacket(character, packet, header) == false)
                        {
                            Program.MainForm.LogAppend(
                                "[{0}] Unknown packet received! " + packet,
                                header
                                );
                        }

                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Program.MainForm.LogAppend($"---- ERROR ----\r\n{ex}");
                Program.MainForm.LogAppend($"Packet: {packet}");
                FileWriter.WriteLine(@"etclog\ExceptionCatcher.log", "[Game Server " + Server.Instance.ID + "][" + DateTime.Now + "] Exception caught: " + ex, true);
                //Disconnect();
            }


#if DEBUG
            if (packet.Length != packet.Position)
            {
                var packetStr = packet.ToString();
                packetStr = packetStr.Substring(0, packet.Position * 3 - 1) + "-x-" + packetStr.Substring(packet.Position * 3);

                log.Debug($"Did not read full message in packet: {header} {packetStr}");
            }
#endif
        }
Exemplo n.º 8
0
        public static void HandleCashItem(Character chr, Packet packet)
        {
            short slot   = packet.ReadShort();
            int   itemid = packet.ReadInt();

            BaseItem item = chr.Inventory.GetItem(2, slot);

            if (chr.AssertForHack(item == null, "HandleCashItem with null item") ||
                chr.AssertForHack(item.ItemID != itemid, "HandleCashItem with itemid inconsistency") ||
                chr.AssertForHack(!DataProvider.Items.TryGetValue(itemid, out var data), "HandleCashItem with unknown item") ||
                chr.AssertForHack(!data.Cash, "HandleCashItem with non-cash item"))
            {
                return;
            }

            var itemType = (Constants.Items.Types.ItemTypes)Constants.getItemType(itemid);

            bool used = false;

            switch (itemType)
            {
            case Constants.Items.Types.ItemTypes.ItemWeather:
                used = chr.Field.MakeWeatherEffect(itemid, packet.ReadString(), new TimeSpan(0, 0, 30));
                break;

            case Constants.Items.Types.ItemTypes.ItemJukebox:
                used = chr.Field.MakeJukeboxEffect(itemid, chr.Name, packet.ReadInt());
                break;

            case Constants.Items.Types.ItemTypes.ItemPetTag:
            {
                var name    = packet.ReadString();
                var petItem = chr.GetSpawnedPet();
                if (petItem != null &&
                    !chr.IsInvalidTextInput("Pet name tag", name, Constants.MaxPetName, Constants.MinPetName))
                {
                    petItem.Name = name;
                    PetsPacket.SendPetNamechange(chr, petItem.Name);
                    used = true;
                }
            }

            break;

            case Constants.Items.Types.ItemTypes.ItemMegaPhone:
            {
                var text = packet.ReadString();
                if (!chr.IsInvalidTextInput("Megaphone item", text, Constants.MaxSpeakerTextLength))
                {
                    switch (itemid)
                    {
                    case 2081000:             // Super Megaphone (channel)
                        MessagePacket.SendMegaphoneMessage(chr.Name + " : " + text);
                        used = true;
                        break;

                    case 2082000:             // Super Megaphone
                        Server.Instance.CenterConnection.PlayerSuperMegaphone(
                            chr.Name + " : " + text,
                            packet.ReadBool()
                            );
                        used = true;
                        break;
                    }
                }
            }
            break;

            case Constants.Items.Types.ItemTypes.ItemKite:
                if (chr.Field.Kites.Count > 0)
                {
                    //Todo : check for character positions..?
                    MapPacket.KiteMessage(chr);
                }
                else
                {
                    string message = packet.ReadString();
                    Kite   pKite   = new Kite(chr, chr.ID, itemid, message, chr.Field);

                    used = true;
                }
                break;

            case Constants.Items.Types.ItemTypes.ItemMesoSack:
                if (data.Mesos > 0)
                {
                    int amountGot = chr.AddMesos(data.Mesos);

                    MiscPacket.SendGotMesosFromLucksack(chr, amountGot);
                    used = true;
                }
                break;

            case Constants.Items.Types.ItemTypes.ItemTeleportRock:
            {
                byte mode = packet.ReadByte();
                int  map  = -1;
                if (mode == 1)
                {
                    string    name   = packet.ReadString();
                    Character target = Server.Instance.GetCharacter(name);
                    if (target != null && target != chr)
                    {
                        map  = target.MapID;
                        used = true;
                    }
                    else
                    {
                        SendRockError(chr, RockErrors.DifficultToLocate);
                    }
                }
                else
                {
                    map = packet.ReadInt();
                    if (!chr.Inventory.HasRockLocation(map))
                    {
                        map = -1;
                    }
                }

                if (map != -1)
                {
                    //I don't think it's even possible for you to be in a map that doesn't exist and use a Teleport rock?
                    Map from = chr.Field;
                    Map to   = DataProvider.Maps.ContainsKey(map) ? DataProvider.Maps[map] : null;

                    if (to == from)
                    {
                        SendRockError(chr, RockErrors.AlreadyThere);
                    }
                    else if (from.Limitations.HasFlag(FieldLimit.TeleportItemLimit))
                    {
                        SendRockError(chr, RockErrors.CannotGo);
                    }
                    else if (chr.AssertForHack(chr.PrimaryStats.Level < 7, "Using telerock while not lvl 8 or higher."))
                    {
                        // Hacks.
                    }
                    else
                    {
                        chr.ChangeMap(map);
                        used = true;
                    }
                }

                break;
            }

            default:
                Program.MainForm.LogAppend("Unknown cashitem used: {0} {1} {2}", itemType, itemid, packet.ToString());
                break;
            }

            if (used)
            {
                ItemTransfer.ItemUsed(chr.ID, item.ItemID, 1, "");
                chr.Inventory.TakeItem(item.ItemID, 1);
            }
            else
            {
                InventoryPacket.NoChange(chr);
            }
        }
Exemplo n.º 9
0
        public void OnVarset(Character Sent, string Var, object Value, object Value2 = null, object Value3 = null)
        {
            if (this != Sent && Sent.IsGM && !Sent.IsAdmin) //Todo Admin levels
            {
                MessagePacket.SendNotice("You don't have the premission to edit other players stats!", Sent);
                //$"{Sent.Name} tried to edit another players stats without premission"
            }
            else
            {
                try
                {
                    MapPacket.AvatarModFlag        AvatarMod = 0;
                    CharacterStatsPacket.StatFlags dwFlag    = 0;

                    switch (Var.ToLower())
                    {
                    case "hp":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Hp;
                        PrimaryStats.HP = Convert.ToInt16(Value);
                        break;

                    case "mp":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Mp;
                        PrimaryStats.MP = Convert.ToInt16(Value);
                        break;

                    case "exp":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Exp;
                        PrimaryStats.EXP = Convert.ToInt32(Value);
                        break;

                    case "maxhp":
                        dwFlag |= CharacterStatsPacket.StatFlags.MaxHp;
                        if (Value.ToString() == "0")
                        {
                            Value = "1";
                        }
                        PrimaryStats.MaxHP = Convert.ToInt16(Value);
                        break;

                    case "maxmp":
                        dwFlag |= CharacterStatsPacket.StatFlags.MaxMp;
                        if (Value.ToString() == "0")
                        {
                            Value = "1";
                        }
                        PrimaryStats.MaxMP = Convert.ToInt16(Value);
                        break;

                    case "ap":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Ap;
                        PrimaryStats.AP = Convert.ToInt16(Value);
                        break;

                    case "sp":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Sp;
                        PrimaryStats.SP = Convert.ToInt16(Value);
                        break;

                    case "str":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Str;
                        PrimaryStats.Str = Convert.ToInt16(Value);
                        break;

                    case "dex":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Dex;
                        PrimaryStats.Dex = Convert.ToInt16(Value);
                        break;

                    case "int":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Int;
                        PrimaryStats.Int = Convert.ToInt16(Value);
                        break;

                    case "luk":
                        dwFlag          |= CharacterStatsPacket.StatFlags.Luk;
                        PrimaryStats.Luk = Convert.ToInt16(Value);
                        break;

                    case "fame":
                    case "pop":
                        dwFlag           |= CharacterStatsPacket.StatFlags.Fame;
                        PrimaryStats.Fame = Convert.ToInt16(Value);
                        break;

                    case "mesos":
                        dwFlag         |= CharacterStatsPacket.StatFlags.Mesos;
                        Inventory.Mesos = Convert.ToInt32(Value);
                        break;

                    case "job":
                    {
                        var Job = Convert.ToInt16(Value);
                        if (DataProvider.HasJob(Job) || Job == 0)
                        {
                            dwFlag          |= CharacterStatsPacket.StatFlags.Job;
                            PrimaryStats.Job = Job;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Job {Job} does not exist.", Sent);
                        }
                        break;
                    }

                    case "skill":
                    {
                        var SkillID = Convert.ToInt32(Value);
                        if (DataProvider.Skills.TryGetValue(SkillID, out var Skill))
                        {
                            if (Value2 == null)
                            {
                                Value2 = Skill.MaxLevel;
                            }
                            Skills.SetSkillPoint(SkillID, Convert.ToByte(Value2), true);
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Skill {SkillID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "level":
                        dwFlag |= CharacterStatsPacket.StatFlags.Level;
                        Level   = Convert.ToByte(Value);
                        MapPacket.SendPlayerLevelupAnim(this);
                        break;

                    case "skin":
                    {
                        var SkinID = Convert.ToByte(Value);
                        if (SkinID >= 0 && SkinID < 6)
                        {
                            AvatarMod |= MapPacket.AvatarModFlag.Skin;
                            dwFlag    |= CharacterStatsPacket.StatFlags.Skin;
                            Skin       = SkinID;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Skin {SkinID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "face":
                    {
                        var FaceID = Convert.ToInt32(Value);
                        if (DataProvider.Equips.ContainsKey(FaceID))
                        {
                            AvatarMod |= MapPacket.AvatarModFlag.Face;
                            dwFlag    |= CharacterStatsPacket.StatFlags.Eyes;
                            Face       = FaceID;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Face {FaceID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "hair":
                    {
                        var HairID = Convert.ToInt32(Value);
                        if (DataProvider.Equips.ContainsKey(HairID))
                        {
                            AvatarMod |= MapPacket.AvatarModFlag.Equips;
                            dwFlag    |= CharacterStatsPacket.StatFlags.Hair;
                            Hair       = HairID;
                        }
                        else
                        {
                            MessagePacket.SendNotice($"Hair {HairID} does not exist.", Sent);
                        }
                        break;
                    }

                    case "gender":
                    {
                        Gender = ParseGenderString(Value.ToString());
                        Server.Instance.CharacterDatabase.RunQuery(
                            "UPDATE characters SET gender = @gender WHERE id = @id",
                            "@gender", Gender,
                            "@id", ID
                            );

                        MessagePacket.SendNotice($"Gender set to {(Gender == 0 ? "male" : (Gender == 2 ? "Unisex" : "female"))}. Please relog.", this);
                        break;
                    }

                    case "accgender":
                    {
                        var gender = ParseGenderString(Value.ToString());
                        Server.Instance.CharacterDatabase.RunQuery(
                            "UPDATE users SET gender = @gender WHERE ID = @id",
                            "@gender", gender,
                            "@id", UserID
                            );

                        MessagePacket.SendNotice($"Account gender set to {(gender == 0 ? "male" : (gender == 2 ? "Unisex" : "female"))}", this);
                        break;
                    }

                    case "map":
                    case "field":
                    {
                        var FieldID = Convert.ToInt32(Value);
                        if (DataProvider.Maps.ContainsKey(FieldID))
                        {
                            ChangeMap(FieldID);
                        }
                        else
                        {
                            MessagePacket.SendText(MessagePacket.MessageTypes.RedText, "Map not found.", this, MessagePacket.MessageMode.ToPlayer);
                        }
                        break;
                    }

                    default:
                        MessagePacket.SendNotice($"{Var} is not a valid Variable!", Sent);
                        return;
                    }

                    if (dwFlag != 0)
                    {
                        CharacterStatsPacket.SendUpdateStat(this, true, dwFlag);
                    }

                    if (AvatarMod != 0)
                    {
                        MapPacket.SendAvatarModified(this, AvatarMod);
                    }
                }
                catch (Exception ex)
                {
                    MessagePacket.SendNotice(ex.Message, Sent);
                }
            }
        }
Exemplo n.º 10
0
 public void OnPetVarset(string Var, string Value, bool Me)
 {
     MessagePacket.SendNotice("Did you hear a cat just now? That damn thing haunts me.", this);
 }
Exemplo n.º 11
0
        public static void HandleInventoryPacket(Character chr, Packet packet)
        {
            try
            {
                byte  inventory = packet.ReadByte();
                short slotFrom  = packet.ReadShort(); // Slot from
                short slotTo    = packet.ReadShort(); // Slot to

                if (slotFrom == 0 || inventory < 0 || inventory > 5)
                {
                    goto no_op;
                }

                Trace.WriteLine($"Trying to swap from {slotFrom} to {slotTo}, inventory {inventory}");
                if (slotFrom < 0)
                {
                    Trace.WriteLine("From: " + (Constants.EquipSlots.Slots)((-slotFrom) % 100));
                }
                if (slotTo < 0)
                {
                    Trace.WriteLine("To: " + (Constants.EquipSlots.Slots)((-slotTo) % 100));
                }

                var itemFrom = chr.Inventory.GetItem(inventory, slotFrom); // Item being moved
                var itemTo   = chr.Inventory.GetItem(inventory, slotTo);   // Item in target position, if any

                if (itemFrom == null)
                {
                    goto no_op;                   // Packet Editing, from slot contains no item.
                }
                if (slotTo < 0 && slotFrom < 0)
                {
                    goto no_op;                             // Packet Editing, both target and source slots are in equip.
                }
                if (slotFrom > 0 && slotTo < 0)
                {
                    Trace.WriteLine($"HandleEquip");
                    HandleEquip(chr, itemFrom, itemTo, slotFrom, slotTo);
                }
                else if (slotFrom < 0 && slotTo > 0)
                {
                    Trace.WriteLine($"Unequip");
                    Unequip(chr, itemFrom, slotTo);
                }
                else if (slotTo == 0)
                {
                    if (chr.IsGM && !chr.IsAdmin)
                    {
                        MessagePacket.SendAdminWarning(chr, "You cannot drop items.");
                        NoChange(chr);
                    }
                    else
                    {
                        var quantity = packet.ReadShort();
                        DropItem(chr, inventory, slotFrom, quantity);
                    }
                }
                else
                {
                    Trace.WriteLine($"Changing slot");
                    ChangeSlot(chr, itemFrom, itemTo, slotFrom, slotTo);
                }

                chr.PrimaryStats.CheckBoosters();

                // TO-DO: Pets + Rings

                return;
            }
            catch (Exception ex)
            {
                Program.MainForm.LogAppend("[{0}] Exception item movement handler: {1}", chr.ID, ex.ToString());
            }

no_op:
            Trace.WriteLine($"Sending nochange!");
            NoChange(chr);
        }