예제 #1
0
        public static void Handle(MapleClient c, PacketReader pr)
        {
            MapleCharacter chr = c.Account.Character;

            if (!chr.DisableActions(ActionState.NpcTalking))
            {
                return;
            }
            try
            {
                int       objectId = pr.ReadInt();
                WzMap.Npc npc      = chr.Map.GetNpc(objectId);
                if (npc == null)
                {
                    ServerConsole.Warning("NPC is not on player {0}'s map: {1}", chr.Name, chr.Map.MapId);
                    chr.EnableActions();
                    return;
                }
                NpcEngine.OpenNpc(npc.Id, objectId, c);
            }
            catch (Exception ex)
            {
                ServerConsole.Error("NpcChatHandler.Handle : " + ex);
                chr.EnableActions();
            }
        }
예제 #2
0
 public EventEngine(MapleCharacter starter, string script, int recreateMap = -1, bool skipSpawn = false)
 {
     Starter   = starter;
     ChannelId = Starter.Client.Channel;
     if (!(DataBuffer.EventScripts.TryGetValue(script, out EventType) && EventType != null))
     {
         return;
     }
     EventInstance = ScriptActivator.CreateScriptInstance(EventType, script, starter) as EventScript;
     if (EventInstance == null)
     {
         string error = string.Format("Error loading {0} {1}", "EventScript", script);
         ServerConsole.Error(error);
         FileLogging.Log("Event scripts", error);
         return;
     }
     RecreatedMap                     = recreateMap != -1;
     EventInstance.OnFinish          += new Action(FinishEvent);
     EventInstance.OnSpawnMobs       += new Action <int, int, int, int>(SpawnMobs);
     EventInstance.OnRandomSpawnMobs += new Action <int, int, Point, Point>(RandomSpawnMobs);
     if (RecreatedMap)
     {
         EventMap = new MapleEvent(recreateMap, DataBuffer.GetMapById(recreateMap), skipSpawn);
         EventId  = Program.RegisterEvent(EventMap);
         if (Starter != null)
         {
             AddCharacter(Starter);
         }
     }
 }
예제 #3
0
        private void OnNewClientConnect(IAsyncResult iar)
        {
            if (Disposed)
            {
                return;
            }
            Socket clientsocket;

            try
            {
                clientsocket = Listener.EndAcceptSocket(iar);
            }
            catch (Exception e)
            {
                if (!Disposed)
                {
                    Listener.BeginAcceptSocket(OnNewClientConnect, null);
                }
                ServerConsole.Error(String.Format("EndAccept Server Error: {0}", e));
                return; //Intentional, we have to scap this connection but still let the listener survive.
            }

            try
            {
                Listener.BeginAcceptSocket(OnNewClientConnect, null);
                if (OnClientConnected != null)
                {
                    OnClientConnected(clientsocket);
                }
            }
            catch (Exception ex)
            {
                ServerConsole.Error(String.Format("Server Error: {0}", ex));
            }
        }
예제 #4
0
        public void ApplyBuffEffect(MapleCharacter target)
        {
            if (Parent.SkillId == Priest.HOLY_MAGIC_SHELL && target.HasSkillOnCooldown(Priest.HOLY_MAGIC_SHELL + 1000))
            {
                return;
            }

            int time;

            if (Info.TryGetValue(CharacterSkillStat.time, out time))
            {
                ulong ltime = 1000 * (ulong)time;
                if (ltime >= int.MaxValue)
                {
                    ltime = MAX_BUFF_TIME_MS;
                }
                uint uTime = (uint)Math.Min(((target.Stats.BuffTimeR / 100.0) * ltime), SkillEffect.MAX_BUFF_TIME_MS);
                Buff buff  = new Buff(Parent.SkillId, this, uTime, target, DateTime.UtcNow);
                target.GiveBuff(buff);
            }
            else
            {
                ServerConsole.Error("Buff from skill " + Parent.SkillId + " has no buff time");
            }
        }
예제 #5
0
 public void SetDefaultStats(WzEquip info, bool randomizeStats = false, bool addRandomPotential = false)
 {
     UpgradeCount   = 0;
     Enhancements   = 0;
     Diligence      = 0;
     CustomLevel    = 0;
     CustomExp      = 0;
     HammersApplied = 0;
     if (info != null)
     {
         RemainingUpgradeCount = info.TotalUpgradeCount;
         if (randomizeStats)
         {
             Str    = GetRandomizedStat(info.IncStr);
             Int    = GetRandomizedStat(info.IncInt);
             Dex    = GetRandomizedStat(info.IncDex);
             Luk    = GetRandomizedStat(info.IncLuk);
             IncMhp = GetRandomizedStat(info.IncMhp);
             IncMmp = GetRandomizedStat(info.IncMmp);
             Pad    = GetRandomizedStat(info.IncPad);
             Mad    = GetRandomizedStat(info.IncMad);
             Pdd    = GetRandomizedStat(info.IncPdd);
             Mdd    = GetRandomizedStat(info.IncMdd);
             Acc    = GetRandomizedStat(info.IncAcc);
             Eva    = GetRandomizedStat(info.IncEva);
             Speed  = GetRandomizedStat(info.IncSpeed);
             Jump   = GetRandomizedStat(info.IncJump);
         }
         else
         {
             Str    = info.IncStr;
             Int    = info.IncInt;
             Dex    = info.IncDex;
             Luk    = info.IncLuk;
             IncMhp = info.IncMhp;
             IncMmp = info.IncMmp;
             Pad    = info.IncPad;
             Mad    = info.IncMad;
             Pdd    = info.IncPdd;
             Mdd    = info.IncMdd;
             Acc    = info.IncAcc;
             Eva    = info.IncEva;
             Speed  = info.IncSpeed;
             Jump   = info.IncJump;
         }
         if (addRandomPotential) //todo: check if this equip can have potential
         {
             MapleEquipEnhancer.AddRandomPotential(this, equipInfo: info);
         }
     }
     else
     {
         ServerConsole.Error("Equip id {0} not in Data Buffer!", ItemId);
     }
 }
예제 #6
0
 internal void RecvPacket(PacketReader packet)
 {
     try
     {
         RecvPacketHandler.Handle(packet, this);
     }
     catch (Exception e)
     {
         ServerConsole.Error(e.ToString());
         FileLogging.Log("PacketExceptions.txt", e.ToString());
     }
 }
예제 #7
0
        public static void Handle(MapleClient c, PacketReader pr)
        {
            try
            {
                if (c.Account == null)
                {
                    c.Disconnect("Client is not logged in to an account");
                    return;
                }

                string pic         = pr.ReadMapleString();
                int    characterId = pr.ReadInt();
                pr.Skip(1);
                string macs     = pr.ReadMapleString();
                string clientid = pr.ReadMapleString();
                if (c.Account.CheckPic(pic) && c.Account.HasCharacter(characterId) && Program.ChannelServers.ContainsKey(c.Channel))
                {
                    ushort port = Program.ChannelServers[c.Channel].Port;
                    c.Account.MigrationData.CharacterId      = characterId;
                    c.Account.MigrationData.Character        = MapleCharacter.LoadFromDatabase(characterId, false);
                    c.Account.MigrationData.Character.Hidden = c.Account.IsGM;

                    Program.EnqueueMigration(characterId, c.Account.MigrationData);

                    c.SendPacket(ChannelIpPacket(port, characterId));
                }
                else
                {
                    //Incorrect Pic
                    PacketWriter pw = new PacketWriter();
                    pw.WriteHeader(SendHeader.PICResponse);
                    pw.WriteByte(0x14);
                    c.SendPacket(pw);
                }
            }
            catch (Exception ex)
            {
                ServerConsole.Error(ex.ToString());
                FileLogging.Log("Character loading", ex.ToString());
                c.SendPacket(MapleCharacter.ServerNotice("Error loading character", 1));

                /*PacketWriter pw = new PacketWriter();
                 * pw.WriteHeader(SendHeaders.PICResponse);
                 * pw.WriteByte(0x15);
                 * c.SendPacket(pw);*/
            }
        }
예제 #8
0
        /// <summary>
        /// Creates a new instance of parameter scriptType as a Script object
        /// </summary>
        /// <param name="scriptType">The type of the script to be instantialized</param>
        /// <param name="scriptName">The name of the script</param>
        /// <param name="chr">The character that triggered the creation of the script</param>
        /// <returns>The created Script instance</returns>
        public static Script CreateScriptInstance(Type scriptType, string scriptName, MapleCharacter chr)
        {
            var instance = Activator.CreateInstance(scriptType) as Script;

            if (instance == null)
            {
                ServerConsole.Error(string.Format("Type {0} cannot be cast to 'Script'", scriptType));
                return(null);
            }
            if (instance is CharacterScript)
            {
                CharacterScript cInstance = (CharacterScript)instance;
                cInstance.Character = new ScriptCharacter(chr, scriptName);
            }
            instance.DataProvider = ScriptDataProvider;
            return(instance);
        }
예제 #9
0
        public void AcceptTrade(MapleCharacter chr)
        {
            if (Type != TradeType.Trade) return;
            if (Partners.Count == 1 && chr == Owner)
            {
                OwnerAccepted = true;
                Partners[0].Client.SendPacket(GenerateTradeAccepted());
            }
            else if (Partners.Count == 1 && chr == Partners[0])
            {
                PartnerAccepted = true;
                Owner.Client.SendPacket(GenerateTradeAccepted());
            }
            else
            {
                ServerConsole.Error("Unable to accept trade because this character isn't registered as in the trade. Partner count " + Partners.Count);
                return;
            }
            if (OwnerAccepted && PartnerAccepted)
            {
                TradeItem[] ownersItems = items[0];
                TradeItem[] partnersItems = items[1];

                MapleCharacter partner = Partners[0];
                MapleCharacter owner = Owner;
                if (OwnerMesos + partner.Inventory.Mesos <= GameConstants.MAX_MESOS && PartnerMesos + owner.Inventory.Mesos <= GameConstants.MAX_MESOS &&
                    CanTransferItems(ownersItems, partner) && CanTransferItems(partnersItems, owner))
                {
                    Close(true, true);
                    TransferItems(ownersItems, owner, partner);
                    TransferItems(partnersItems, partner, owner);
                    Owner.Inventory.RemoveMesos(OwnerMesos, false);
                    partner.Inventory.RemoveMesos(PartnerMesos, false);

                    Owner.Inventory.GainMesos(PartnerMesos, false);
                    partner.Inventory.GainMesos(OwnerMesos, false);
                }
                else //Items cant be transfered
                {
                    Close(true, false);
                }
            }
        }
예제 #10
0
        public BoundingBox CalculateBoundingBox(Point origin, bool facingLeft)
        {
            int range;

            if (Info.TryGetValue(CharacterSkillStat.range, out range))
            {
                if (facingLeft)
                {
                    return(new BoundingBox(origin.X - range, origin.Y - 100, origin.X, origin.Y));
                }
                else
                {
                    return(new BoundingBox(origin.X, origin.Y - 100, origin.X + range, origin.Y));
                }
            }
            else
            {
                ServerConsole.Error("Skill " + Parent.SkillId + " is a Party ability but has no bounding box or range attributes");
            }
            return(new BoundingBox());
        }
예제 #11
0
        public NpcEngine(MapleClient c, int id)
        {
            Client = c;
            NpcId  = id;
            Type npcT;

            if (DataBuffer.NpcScripts.TryGetValue(NpcId, out npcT) && npcT != null)
            {
                ScriptInstance = ScriptActivator.CreateScriptInstance(npcT, npcT.ToString(), c.Account.Character) as NpcScript;
                if (ScriptInstance == null)
                {
                    string error = string.Format("Error loading {0} {1}", "NpcScript", npcT.ToString());
                    ServerConsole.Error(error);
                    FileLogging.Log("Npc scripts", error);
                    return;
                }
                if (ScriptInstance.IsShop)
                {
                    IsShop = true;
                }
                else
                {
                    ScriptInstance.SendOk       = new Action <string>(SendOk);
                    ScriptInstance.SendNext     = new Action <string>(SendNext);
                    ScriptInstance.SendPrev     = new Action <string>(SendPrev);
                    ScriptInstance.SendNextPrev = new Action <string>(SendNextPrev);
                    ScriptInstance.SendSimple   = new Action <string>(SendSimple);
                    ScriptInstance.EndChat      = new Action(Dispose);
                    ScriptInstance.SendYesNo    = new Action <string>(SendYesNo);
                    ScriptInstance.SendAskText  = new Action <string, int, int, string>(SendAskText);
                }
            }
            else
            {
                SendOk(string.Format(@"An error has occured in my script. Please report this as a bug\r\nNpcId: {0}", NpcId));
                ServerConsole.Debug(string.Format(@"Missing script for NPC: {0}", NpcId));
                ScriptInstance = null;
                c.Account.Character.EnableActions();
            }
        }
예제 #12
0
 public static void EnterScriptedPortal(WzMap.Portal portal, MapleCharacter character)
 {
     if (!string.IsNullOrEmpty(portal.Script))
     {
         Type portalScriptType;
         if (DataBuffer.PortalScripts.TryGetValue(portal.Script, out portalScriptType) && portalScriptType != null)
         {
             PortalScript scriptInstance = Activator.CreateInstance(portalScriptType) as PortalScript;
             if (scriptInstance == null)
             {
                 string error = string.Format("Error loading {0} {1}", "PortalScript", portal.Script);
                 ServerConsole.Error(error);
                 FileLogging.Log("Portal scripts", error);
                 return;
             }
             scriptInstance.Character = new ScriptCharacter(character, portal.Script);
             try
             {
                 scriptInstance.Execute();
             }
             catch (Exception e)
             {
                 string error = string.Format("Script: {0} error: {1}", portal.Script, e);
                 FileLogging.Log("Portal scripts", error);
                 ServerConsole.Debug("Portal script execution error: " + error);
                 character.EnableActions();
             }
         }
         else
         {
             character.SendBlueMessage(string.Format("This portal is not coded yet (mapId: {0}, portalId: {1}, script name: {2})", character.MapId, portal.Id, portal.Script));
             character.EnableActions();
         }
     }
     else
     {
         character.EnableActions();
     }
 }
예제 #13
0
        public static bool IsValidCharacter(JobType type, byte gender, int hair, int face, Dictionary <MapleEquipPosition, int> equips, int hairColor, int skinColor, int demonMark, int tamerEars, int tamerTail)
        {
            if (!IsValidId(type, gender, face, 0) || !IsValidId(type, gender, hair, 1))
            {
                return(false);
            }
            try
            {
                switch (type)
                {
                case JobType.Explorer:
                case JobType.DualBlade:
                case JobType.Cannonneer:
                case JobType.Cygnus:
                    if (!IsValidId(type, gender, skinColor, 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5))
                    {
                        return(false);
                    }
                    break;

                case JobType.Resistance:
                case JobType.Aran:
                case JobType.Evan:
                    if (!IsValidId(type, gender, hairColor, 2) || !IsValidId(type, gender, skinColor, 3) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Top], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Bottom], 5) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7))
                    {
                        return(false);
                    }
                    break;

                case JobType.Jett:
                    if (!IsValidId(type, gender, equips[MapleEquipPosition.Top], 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Cape], 3) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5))
                    {
                        return(false);
                    }
                    break;

                case JobType.Mercedes:
                    if (!IsValidId(type, gender, equips[MapleEquipPosition.Top], 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 3) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 4))
                    {
                        return(false);
                    }
                    break;

                case JobType.Phantom:
                case JobType.Luminous:
                    if (!IsValidId(type, gender, skinColor, 2) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Cape], 4) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 6))
                    {
                        return(false);
                    }
                    break;

                case JobType.Demon:
                    if (!IsValidId(type, gender, demonMark, 2) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.SecondWeapon], 6))
                    {
                        return(false);
                    }
                    break;

                case JobType.Xenon:
                    if (!IsValidId(type, gender, hairColor, 2) || !IsValidId(type, gender, skinColor, 3) ||
                        !IsValidId(type, gender, demonMark, 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 5) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7))
                    {
                        return(false);
                    }
                    break;

                case JobType.Hayato:
                case JobType.Kanna:
                    if (!IsValidId(type, gender, hairColor, 2) || !IsValidId(type, gender, skinColor, 3) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Hat], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 5) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7))
                    {
                        return(false);
                    }
                    break;

                case JobType.Mihile:
                    if (!IsValidId(type, gender, skinColor, 3) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Top], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Bottom], 5) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7))
                    {
                        return(false);
                    }
                    break;

                case JobType.Kaiser:
                case JobType.AngelicBuster:
                    if (!IsValidId(type, gender, skinColor, 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5))
                    {
                        return(false);
                    }
                    break;

                case JobType.BeastTamer:
                    if (!IsValidId(type, gender, skinColor, 2) || !IsValidId(type, gender, demonMark, 3) ||
                        !IsValidId(type, gender, tamerEars, 4) || !IsValidId(type, gender, tamerTail, 5) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Top], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 7) ||
                        !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 8))
                    {
                        return(false);
                    }
                    break;

                default:
                    ServerConsole.Error("Could not validate newly created character because job " + type + " is not handled");
                    return(false);
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
        public static void Handle(MapleClient c, PacketReader pr)
        {
            //6800 29939E7B 81BFD40F FD 00 60000000 00 00 037B 00
            //6800 418AE151 6BE4D40F FF 00 01000000 00 00 47357C00 FE77AD00 00 00000000 00000000 00 00 00

            //C101 CA566800 FD 60000000 00 60000000
            //C101 68EB7A00 FF 01000000 00 F6761200 00 00000000 00000000 00 00 01000000

            //effect
            //CD01 CA566800 [000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200] 0100 7B000300 00 00 00 00000000 00000000 00000000 00000000 00000000 0000
            MapleCharacter chr = c.Account.Character;

            if (chr.Hidden)
            {
                return;
            }
            pr.Skip(4); //rnd num
            pr.Skip(4); //tickcount
            byte type   = pr.ReadByte();
            int  damage = 0;

            pr.ReadByte();
            damage = pr.ReadInt();
            pr.Skip(2);
            int fake = 0;

            if (damage == -1)
            {
                fake = 4020002 + (chr.Job / 10 - 40) * 100000;
                if ((fake != NightLord.SHADOW_SHIFTER) && (fake != Shadower.SHADOW_SHIFTER))
                {
                    fake = NightLord.SHADOW_SHIFTER;
                }
            }
            switch (type)
            {
            case 0xFF:    //mob damage
            {
                int          mobid = pr.ReadInt();
                int          oid   = pr.ReadInt();
                MapleMonster mob   = chr.Map.GetMob(oid);
                if (mob == null)
                {
                    return;
                }
                byte  direction = pr.ReadByte();
                int   skillid   = pr.ReadInt();
                int   pDmg      = pr.ReadInt();
                byte  defType   = pr.ReadByte();
                bool  pPhysical = false;
                int   pId       = 0;
                byte  pType     = 0;
                Point pPos      = Point.Empty;
                pr.ReadByte();
                if (skillid != 0)
                {
                    pPhysical = pr.ReadBool();
                    pId       = pr.ReadInt();
                    pType     = pr.ReadByte();
                    pr.Skip(4);
                    pPos = pr.ReadPoint();
                }
                byte offset  = 0;
                int  offsetD = 0;
                if (pr.Available == 1L)
                {
                    offset = pr.ReadByte();
                    if ((offset == 1) && (pr.Available >= 4L))
                    {
                        offsetD = pr.ReadInt();
                    }
                    if ((offset < 0) || (offset > 2))
                    {
                        offset = 0;
                    }
                }
                BroadcastDamagePlayerPacket(chr, type, damage, mobid, direction, skillid, pDmg, pPhysical, pId, pType, pPos, offset, offsetD, fake);
                damage = DoMonsterDamageModifiers(damage, chr, mob, oid);
                if (damage > 0)
                {
                    chr.AddHP(-damage);
                }
            }
            break;

            case 0xFD:                        //no mob, such as fall damage
            {
                short skill = pr.ReadShort(); //skill
                pr.ReadByte();                //?

                byte offset  = 0;
                int  offsetD = 0;
                if (pr.Available >= 1)
                {
                    offset = pr.ReadByte();
                    if ((offset == 1) && (pr.Available >= 4))
                    {
                        offsetD = pr.ReadInt();
                    }
                    if ((sbyte)offset < 0 || offset > 2)
                    {
                        offset = 0;
                    }
                }
                BroadcastDamagePlayerPacket(chr, type, damage, 0, 0, 0, 0, false, 0, 0, System.Drawing.Point.Empty, offset, offsetD, fake);
                if (damage > 0)
                {
                    chr.AddHP(-damage);
                }
            }
            break;

            default:
                ServerConsole.Error("Invalid CharacterReceiveDamage type {0} ", type);
                break;
            }
        }
예제 #15
0
        public static short GetJobIdByJobType(JobType jobType)
        {
            switch (jobType)
            {
            case JobType.Ultimate:
            case JobType.Explorer:
            case JobType.Cannonneer:
            case JobType.Jett:
            case JobType.DualBlade:
                return(0);

            case JobType.Cygnus:
                return(1000);

            case JobType.Aran:
                return(2000);

            case JobType.Evan:
                return(2001);

            case JobType.Mercedes:
                return(2002);

            case JobType.Phantom:
                return(2003);

            case JobType.Luminous:
                return(2004);

            case JobType.Resistance:
                return(3000);

            case JobType.Demon:
                return(3001);

            case JobType.Xenon:
                return(3002);

            case JobType.Hayato:
                return(4001);

            case JobType.Kanna:
                return(4002);

            case JobType.Mihile:
                return(5000);

            case JobType.Kaiser:
                return(6000);

            case JobType.AngelicBuster:
                return(6001);

            case JobType.Zero:
                return(10000);

            case JobType.BeastTamer:
                return(11000);

            default:
                ServerConsole.Error(String.Format("Unhandled JobType: {0} in CreateCharHandler", jobType));
                return(0);
            }
        }
        public static void Handle(MapleClient c, PacketReader pr)
        {
            try
            {
                if (c.NpcEngine != null && c.NpcEngine.IsShop)
                {
                    byte mode  = pr.ReadByte();
                    int  NpcId = c.NpcEngine.NpcId;
                    switch (mode)
                    {
                    case 0:
                    {
                        short shopIndex = pr.ReadShort();
                        int   itemId    = pr.ReadInt();
                        short amount    = pr.ReadShort();
                        c.NpcEngine.BuyItem(itemId, shopIndex, amount);
                        break;
                    }

                    case 1:     //sell
                    {
                        short inventoryIndex = pr.ReadShort();
                        int   itemId         = pr.ReadInt();
                        short qty            = pr.ReadShort();

                        MapleInventoryType invType = ItemConstants.GetInventoryType(itemId);
                        switch (invType)
                        {
                        case MapleInventoryType.Equip:
                        case MapleInventoryType.Etc:
                        case MapleInventoryType.Setup:
                        case MapleInventoryType.Use:
                            break;

                        default:
                            return;         // Not a valid item
                        }
                        WzItem wzitem = DataBuffer.GetItemById(itemId);
                        if (wzitem == null)
                        {
                            wzitem = DataBuffer.GetEquipById(itemId);
                        }
                        if (wzitem == null)     // Item doesnt exist (anymore?)
                        {
                            return;
                        }
                        if (wzitem.NotSale || wzitem.IsCashItem || wzitem.IsQuestItem)
                        {
                            return;
                        }
                        byte response = 0;
                        if (!wzitem.IsQuestItem)
                        {
                            MapleInventory inventory = c.Account.Character.Inventory;
                            MapleItem      item      = inventory.GetItemSlotFromInventory(invType, inventoryIndex);
                            if (item?.ItemId == itemId && item.Quantity >= qty)
                            {
                                if (inventory.Mesos + wzitem.Price > GameConstants.MAX_MESOS)
                                {
                                    response = 2;     // You do not have enough mesos
                                }
                                else
                                {
                                    inventory.RemoveItemsFromSlot(item.InventoryType, item.Position, qty, true);
                                    inventory.GainMesos(wzitem.Price * qty, false, false);
                                }
                                // TODO: buyback
                            }
                        }
                        PacketWriter pw = new PacketWriter();
                        pw.WriteHeader(SendHeader.NpcTransaction);
                        pw.WriteByte(response);
                        pw.WriteByte(0);
                        pw.WriteByte(0);
                        c.SendPacket(pw);
                        break;
                    }

                    case 3:
                    {
                        c.NpcEngine.Dispose();
                        break;
                    }

                    default:
                    {
                        c.NpcEngine.ScriptInstance = null;
                        ServerConsole.Warning("Unkown NpcShopActionHandler mode:" + mode);
                        ServerConsole.Info(Functions.ByteArrayToStr(pr.ToArray()));
                        break;
                    }
                    }
                }
            }
            catch (Exception ex)
            {
                ServerConsole.Error("NpcShopActionHandler Failure");
                ServerConsole.Error(ex.Message);
                if (c.NpcEngine != null)
                {
                    c.NpcEngine.Dispose();
                }
            }
        }
예제 #17
0
        public static void HandleDistribute(MapleClient c, PacketReader pr)
        {
            MapleCharacter chr = c.Account.Character;

            if (chr.AP == 0)
            {
                return;
            }
            int tickCount  = pr.ReadInt();
            int statsCount = pr.ReadInt();

            Dictionary <MapleCharacterStat, long> statsAssign = new Dictionary <MapleCharacterStat, long>();

            for (int i = 0; i < statsCount; i++)
            {
                MapleCharacterStat stat = (MapleCharacterStat)pr.ReadLong();
                int addValue            = pr.ReadInt();
                if (addValue > 0)
                {
                    statsAssign.Add(stat, addValue);
                }
            }
            SortedDictionary <MapleCharacterStat, long> statsUpdate = new SortedDictionary <MapleCharacterStat, long>();

            foreach (KeyValuePair <MapleCharacterStat, long> kvp in statsAssign)
            {
                if (chr.AP < kvp.Value)
                {
                    continue;
                }
                short statInc = (short)kvp.Value;
                switch (kvp.Key)
                {
                case MapleCharacterStat.Str:
                    if (chr.Str + statInc <= 9999)
                    {
                        chr.Str += statInc;
                        chr.AP  -= statInc;
                        statsUpdate.Add(MapleCharacterStat.Str, chr.Str);
                    }
                    break;

                case MapleCharacterStat.Dex:
                    if (chr.Dex + statInc <= 9999)
                    {
                        chr.Dex += statInc;
                        chr.AP  -= statInc;
                        statsUpdate.Add(MapleCharacterStat.Dex, chr.Dex);
                    }
                    break;

                case MapleCharacterStat.Int:
                    if (chr.Int + statInc <= 9999)
                    {
                        chr.Int += statInc;
                        chr.AP  -= statInc;
                        statsUpdate.Add(MapleCharacterStat.Int, chr.Int);
                    }
                    break;

                case MapleCharacterStat.Luk:
                    if (chr.Luk + statInc <= 9999)
                    {
                        chr.Luk += statInc;
                        chr.AP  -= statInc;
                        statsUpdate.Add(MapleCharacterStat.Luk, chr.Luk);
                    }
                    break;

                default:
                    ServerConsole.Error("Unhandled stat in AutoAssignAp handling: " + kvp.Key);
                    break;
                }
            }
            statsUpdate.Add(MapleCharacterStat.Ap, chr.AP);
            MapleCharacter.UpdateStats(c, statsUpdate, true);
        }
예제 #18
0
        public static void Handle(MapleClient c, PacketReader pr)
        {
            MapleCharacter chr = c.Account.Character;

            try
            {
                if (c.NpcEngine == null || c.NpcEngine.ScriptInstance == null)
                {
                    if (chr.ActionState == ActionState.NpcTalking)
                    {
                        chr.EnableActions();
                    }
                    return;
                }
                int objectId = c.NpcEngine.ScriptInstance.ObjectId;
                if (objectId != -1) //objectId == -1 when npc conversation was started by the server, so players can talk to NPCs that are not on their map (with commands etc)
                {
                    WzMap.Npc npc = chr.Map.GetNpc(objectId);
                    if (npc == null)
                    {
                        c.NpcEngine.ScriptInstance = null;
                        return;
                    }
                }
                byte type = pr.ReadByte();
                byte next = pr.ReadByte();
                if (next == 0xFF) //End Chat
                {
                    c.NpcEngine.Dispose();
                    return;
                }
                if (next == 0 && (type != 2))
                {
                    c.NpcEngine.ScriptInstance.State -= 1;
                }
                else
                {
                    c.NpcEngine.ScriptInstance.State += 1;
                }
                bool execute = false;
                switch (type)
                {
                case 0:     //SendOk, SendPrev, SendNext
                    execute = true;
                    break;

                case 2:     //SendYesNo
                    execute = true;
                    c.NpcEngine.ScriptInstance.Selection = next == 0 ? 0 : 1;
                    break;

                case 3:    //SendAskText
                    if (next == 0)
                    {
                        execute = false;
                    }
                    else
                    {
                        execute = true;
                        string text = pr.ReadMapleString();
                        c.NpcEngine.ScriptInstance.InText = text;
                    }
                    break;

                case 4:     //SendGetNumber
                    //Player.GetNpcStatus().Num = pr.ReadInt();
                    execute = true;
                    break;

                case 5:     //SendSimple
                    if (next == 0)
                    {
                        execute = false;
                    }
                    else
                    {
                        if (pr.Available >= 4)
                        {
                            c.NpcEngine.ScriptInstance.Selection = pr.ReadInt();     //This can be int as well, decided by the client
                        }
                        else if (pr.Available >= 1)
                        {
                            c.NpcEngine.ScriptInstance.Selection = pr.ReadSByte();
                        }
                        execute = true;
                    }
                    break;

                case 23:     //Choose Job
                    int choice = pr.ReadInt();

                    break;

                default:
                    string msg = "Unknown Npc chat type: " + pr.ToString();
                    ServerConsole.Error(msg);
                    FileLogging.Log("NPC chat type", msg);
                    c.NpcEngine.ScriptInstance = null;
                    break;
                }
                if (execute)
                {
                    NpcEngine engine = c.NpcEngine;
                    if (engine == null)
                    {
                        if (c.Account.Character.ActionState == ActionState.NpcTalking)
                        {
                            c.Account.Character.EnableActions();
                        }
                        return;
                    }
                    engine.ExecuteScriptForNpc();
                }
                else
                {
                    c.NpcEngine.ScriptInstance = null;
                    if (chr.ActionState == ActionState.NpcTalking)
                    {
                        chr.EnableActions();
                    }
                }
            }
            catch (Exception ex)
            {
                ServerConsole.Error("NpcChatMoreHandler.Handle : " + ex.ToString());
                if (c.NpcEngine != null)
                {
                    c.NpcEngine.ScriptInstance = null;
                }
                if (chr.ActionState == ActionState.NpcTalking)
                {
                    chr.EnableActions();
                }
            }
        }