//[TestMethod()]
        public void Command_Should_Parse_Correctly()
        {
            // ARRANGE
            Character toon = null;
            InventoryItem invItem = new InventoryItem();

            // Get the client's character info
            string charName = "Badass";
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Character>(c => c.Account);
            dlo.LoadWith<Character>(c => c.Zone);
            dlo.LoadWith<Character>(c => c.InventoryItems);
            dlo.LoadWith<InventoryItem>(ii => ii.Item);
            using (EmuDataContext dbCtx = new EmuDataContext()) {
                dbCtx.ObjectTrackingEnabled = false;
                dbCtx.LoadOptions = dlo;
                toon = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
            }

            ZonePlayer zp = new ZonePlayer(1, toon, 1, new Client(new System.Net.IPEndPoint(0x2414188f, 123)));

            // ACT
            //zp.MsgMgr.ReceiveChannelMessage("someTarget", "!damage /amount:200 /type:3", 8, 0, 100);
            zp.MsgMgr.ReceiveChannelMessage("someTarget", "!damage", 8, 0, 100);

            // ASSERT
        }
        internal void DispatchServerCommand(ZonePlayer zp, ServerCommand cmd, Dictionary<string, string> args)
        {
            switch (cmd) {
                case ServerCommand.Zone:
                    Zone zone;
                    using (EmuDataContext dbCtx = new EmuDataContext()) {
                        dbCtx.ObjectTrackingEnabled = false;
                        zone = dbCtx.Zones.SingleOrDefault(z => z.ShortName == args["name"]);
                    }

                    if (zone != null)
                        MovePlayer(zp, zone.ZoneID, 0u, zone.SafeX, zone.SafeY, zone.SafeZ, 0.0f, ZoneMode.ZoneToSafeCoords);
                    else
                        zp.MsgMgr.SendSpecialMessage(MessageType.Default, "Unable to locate zone " + args["name"]);

                    break;
                case ServerCommand.GoTo:
                    break;
                default:
                    break;
            }
        }
Esempio n. 3
0
        internal override void ServerStarted()
        {
            // Connect to World (really just setting up proxy)
            _worldEA = new EndpointAddress("net.tcp://localhost:8000/WorldService");    // TODO: change to pick up an endpoint in the config file
            _worldSvcClientChannel = new ChannelFactory<IWorldService>(new NetTcpBinding(), _worldEA);
            //_worldSvcClient = new WorldService.WorldServiceClient(new NetTcpBinding(), worldEA);

            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                dbCtx.ObjectTrackingEnabled = false;
                _worldServer = dbCtx.WorldServers.Single(p => p.WorldConfigID == 1);
            }

            base.ServerStarted();
        }
Esempio n. 4
0
        private void ProcessApplicationPacket(EQRawApplicationPacket packet, Client client)
        {
            switch (packet.OpCode)
            {
                case AppOpCode.None:
                    _log.Error("Application OpCode found not set during packet processing... please fix.");
                    break;
                case AppOpCode.SessionReady:
                    //_log.Debug("Received SessionReady OPCode");

                    // Send a chat message - why? I have no idea
                    EQRawApplicationPacket chatPacket = new EQRawApplicationPacket(AppOpCode.ChatMessage, packet.ClientIPE, CHAT_MSG);
                    lock (client.syncRoot)
                        client.SendApplicationPacket(chatPacket);
                    break;
                case AppOpCode.Login:
                    //_log.Debug("Received Login OPCode");

                    // Authenticate - either with IPAddress or netbios name (if local)
                    string hostName = null;
                    if (Utility.IsIpInNetwork(IPAddress.Parse(_worldServer.IPAddress), client.IPEndPoint.Address, IPAddress.Parse("255.255.255.0")))
                        hostName = Dns.GetHostEntry(client.IPEndPoint.Address).HostName;
                    else
                        hostName = client.IPEndPoint.Address.ToString();

                    LoginAccount logAcct = null;
                    using (EmuDataContext dbCtx = new EmuDataContext())
                    {
                        logAcct = dbCtx.LoginAccounts.SingleOrDefault(la => la.IPAddress == hostName);
                    }

                    if (logAcct == null)
                    {
                        _log.InfoFormat("Client ({0}) attempted login but no matching Login Account was found.", hostName);
                        client.Close();
                        return;
                    }

                    _log.InfoFormat("Client ({0}) login successful.", hostName);
                    // TODO: set last login date?

                    // Send a login accepted
                    EQRawApplicationPacket laPacket = new EQRawApplicationPacket(AppOpCode.LoginAccepted, packet.ClientIPE, LOGIN_ACCEPTED_MSG);
                    lock (client.syncRoot)
                        client.SendApplicationPacket(laPacket);
                    break;
                case AppOpCode.ServerListRequest:
                    //_log.Debug("Received ServerListRequest OPCode");
                    SendServerList(client);
                    break;
                case AppOpCode.PlayEverquestRequest:
                    //_log.Debug("Received PlayEverquestRequest OPCode");

                    // TODO: check for locked and admin level

                    // TODO: check for max players and admin level

                    SendPlayResponse(client);
                    break;
                case AppOpCode.EnterChat:
                case AppOpCode.ChatMessage:
                case AppOpCode.Poll:
                default:
                    _log.Warn("Received Unexpected Application OPCode: " + packet.OpCode);
                    break;
            }
        }
        //[TestMethod()]
        public void Weapon_Should_Equip_Correctly()
        {
            // ARRANGE
            Character toon = null;
            InventoryItem invItem = new InventoryItem();
            Item item = null;

            // Get the client's character info
            string charName = "Badass";
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Character>(c => c.Account);
            dlo.LoadWith<Character>(c => c.Zone);
            dlo.LoadWith<Character>(c => c.InventoryItems);
            dlo.LoadWith<InventoryItem>(ii => ii.Item);
            using (EmuDataContext dbCtx = new EmuDataContext()) {
                dbCtx.ObjectTrackingEnabled = false;
                dbCtx.LoadOptions = dlo;
                toon = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
            }

            ZonePlayer zp = new ZonePlayer(1, toon, 1, new Client(new System.Net.IPEndPoint(0x2414188f, 123)));

            // Get the inventory item we're giving to the char
            using (EmuDataContext dbCtx = new EmuDataContext()) {
                dbCtx.ObjectTrackingEnabled = false;
                item = dbCtx.Items.SingleOrDefault(i => i.ItemID == 5023);
            }
            invItem.Item = item;

            // ACT
            zp.AutoGiveItem(ref invItem);

            // ASSERT
        }
Esempio n. 6
0
        /// <summary>Processes the (re)spawning of entities in the zone.  Iterates the spawns for this zone and then adds a corresponding
        /// NPC to the mob list if various spawn conditions are met.</summary>
        private void SpawnTimerCallback(object state)
        {
            NpcMob npcMob = null;
            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                dbCtx.ObjectTrackingEnabled = false;

                List<SkillCap> skillCaps = dbCtx.SkillCaps.OrderBy(sc => sc.SkillID).ThenBy(sc => sc.Class).ThenBy(sc => sc.Level).ToList();

                foreach (Internals.Data.Spawn s in this.Zone.Spawns)
                {
                    // TODO: Handle timeleft on spawn entity (may be able to wait until persistant zone state is in)

                    // TODO: Process spawn conditions

                    if (!s.ReadyForRespawn())
                        continue;

                    try
                    {
                        Npc npc = s.SpawnGroup.PickNPC();   // Get an Npc
                        if (npc != null)
                        {
                            npcMob = new NpcMob(GetNewEntityId(), npc, s.PathGrid, s.X, s.Y, s.Z, s.Heading);

                            // Clean up the npc's name and make it unique (def. before we add to list)
                            npcMob.Name = npcMob.Name.RemoveDigits();
                            npcMob.Name = GetUniqueMobName(npcMob.Name);

                            var npcSkillCaps = skillCaps.Where(sc => sc.Class == npcMob.Class && sc.Level == npcMob.Level);

                            foreach (SkillCap cap in npcSkillCaps)
                                npcMob.SetSkillLevel((Skill)cap.SkillID, cap.Level);

                            //_log.DebugFormat("Trying to add npc with entity id of {0}", npcMob.ID);
                            AddNpc(npcMob, true, false);
                            // TODO: add to npc limit list

                            s.LastSpawned = DateTime.Now;
                            // TODO: set roambox?
                            npcMob.LoadGrid(this.Zone.ZoneID, dbCtx);
                        }
                        else
                        {
                            s.LastSpawned = DateTime.MaxValue;  // better than tracking a separate list of deletes and delete routine?
                            _log.DebugFormat("Spawn {0} removed due to lack of NPCs, spawn groups or cumulative spawn chance of zero.", s.SpawnID);
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error("Error in SpawnTimerCallback", ex);
                    }
                }
            }
        }
        public void Item_Should_Stack_Correctly_In_A_Container()
        {
            // ARRANGE
            Character toon = null;
            InventoryItem invItem = new InventoryItem();
            Item item = null;

            // Get the client's character info
            string charName = "Badass";
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Character>(c => c.Account);
            dlo.LoadWith<Character>(c => c.Zone);
            dlo.LoadWith<Character>(c => c.InventoryItems);
            dlo.LoadWith<InventoryItem>(ii => ii.Item);
            using (EmuDataContext dbCtx = new EmuDataContext()) {
                dbCtx.ObjectTrackingEnabled = false;
                dbCtx.LoadOptions = dlo;
                toon = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
            }

            ZonePlayer zp = new ZonePlayer(1, toon, 1, new Client(new System.Net.IPEndPoint(0x2414188f, 123)));

            // Get the inventory item (bone chips) we're giving to the char
            using (EmuDataContext dbCtx = new EmuDataContext()) {
                dbCtx.ObjectTrackingEnabled = false;
                item = dbCtx.Items.SingleOrDefault(i => i.ItemID == 13073);
            }
            invItem.Item = item;
            invItem.Charges = 1;    // Giving one bone chip

            // ACT
            if (!zp.AutoGiveItem(ref invItem))
                zp.GiveItem(invItem, (int)InventorySlot.Cursor);
        }
Esempio n. 8
0
partial         void OnZoneIDChanged()
        {
            if (this.ZoneID == 0)
                this.ZoneName = string.Empty;
            else
                using (EmuDataContext dbCtx = new EmuDataContext())
                    this.ZoneName = dbCtx.Zones.Single(z => z.ZoneID == this.ZoneID).ShortName;
        }
Esempio n. 9
0
        internal void CmdSummonItem(Dictionary<string, string> arguments)
        {
            string itemIdStr = "0";
            int itemId;

            if (arguments != null)
                arguments.TryGetValue("id", out itemIdStr);

            itemId = int.Parse(itemIdStr);

            // Get the inventory item we're summoning
            InventoryItem invItem = new InventoryItem();
            invItem.Charges = 1;
            Item item = null;
            using (EmuDataContext dbCtx = new EmuDataContext()) {
                dbCtx.ObjectTrackingEnabled = false;
                item = dbCtx.Items.SingleOrDefault(i => i.ItemID == itemId);
            }

            if (item == null) {
                SendSpecialMessage(MessageType.Default, "No item found with that Id.");
                return;
            }

            invItem.Item = item;

            if (_zp.TargetMob == null)
                _zp.GiveItem(invItem, (int)InventorySlot.Cursor);
            else {
                if (_zp.TargetMob is NpcMob)
                    ((NpcMob)_zp.TargetMob).GiveItem(invItem);
                else if (_zp.TargetMob is ZonePlayer)
                    ((ZonePlayer)_zp.TargetMob).GiveItem(invItem, (int)InventorySlot.Cursor);

                SendSpecialMessage(MessageType.Default, "Gave {0} to {1}.", item.Name, _zp.TargetMob.Name);
            }
        }
Esempio n. 10
0
        internal static CharacterSelect GetCharSelectData(int acctId)
        {
            CharacterSelect charSel = new CharacterSelect();

            byte[] noneBuf = Encoding.ASCII.GetBytes("<none>");
            for (int i = 0; i < 10; i++)
                Buffer.BlockCopy(noneBuf, 0, charSel.Name, i * 64, 6);

            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                DataLoadOptions dlo = new DataLoadOptions();
                dlo.LoadWith<Character>(c => c.InventoryItems);
                dlo.LoadWith<InventoryItem>(ii => ii.Item);
                dbCtx.LoadOptions = dlo;

                var characters = from c in dbCtx.Characters
                                 where c.AccountID == acctId
                                 select c;

                int charIdx = 0;
                foreach (Character c in characters) {
                    // character info
                    if (c.Name.Length < 6)
                        Buffer.BlockCopy(Encoding.ASCII.GetBytes(c.Name + "\0\0"), 0, charSel.Name, charIdx * 64, c.Name.Length + 2);
                    else
                        Buffer.BlockCopy(Encoding.ASCII.GetBytes(c.Name), 0, charSel.Name, charIdx * 64, c.Name.Length);
                    charSel.Level[charIdx] = (byte)c.CharLevel;
                    charSel.Class[charIdx] = (byte)c.Class;
                    charSel.Race[charIdx] = (int)c.Race;
                    charSel.Gender[charIdx] = (byte)c.Gender;
                    charSel.Deity[charIdx] = (int)c.Deity;
                    charSel.Zone[charIdx] = (int)c.ZoneID;
                    charSel.HairColor[charIdx] = (byte)c.HairColor;
                    charSel.BeardColor[charIdx] = (byte)c.BeardColor;
                    charSel.EyeColor1[charIdx] = (byte)c.EyeColor1;
                    charSel.EyeColor2[charIdx] = (byte)c.EyeColor2;
                    charSel.Hair[charIdx] = (byte)c.HairStyle;
                    charSel.Beard[charIdx] = (byte)c.Beard;

                    // Get equiped items
                    if (c.InventoryItems.Count > 0) {
                        InventoryManager invMgr = new InventoryManager(c.InventoryItems);

                        for (int equipType = 0; equipType < MAX_EQUIPABLES; equipType++) {
                            InventoryItem ii = invMgr[(int)InventoryManager.GetEquipableSlot((EquipableType)equipType)];
                            if (ii == null)
                                continue;

                            charSel.Equip[charIdx * equipType] = ii.Item.Material;
                            charSel.EquipColors[charIdx * equipType] = ii.Item.Color ?? 0;   // TODO: tints (LoY era)

                            // Held items (set the idfile)
                            if (equipType == (int)EquipableType.Primary || equipType == (int)EquipableType.Secondary) {
                                if (ii.Item.IDFile.Length > 2) {
                                    int idFile = int.Parse(ii.Item.IDFile.Substring(2));
                                    if (equipType == (int)EquipableType.Primary)
                                        charSel.Primary[charIdx] = idFile;
                                    else
                                        charSel.Secondary[charIdx] = idFile;
                                }
                            }
                        }
                    }

                    charIdx++;
                }
            }

            return charSel;
        }
Esempio n. 11
0
        internal static bool ReserveName(int acctId, string name)
        {
            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                if (dbCtx.Characters.Count(c => c.Name == name) > 0)
                    return false;

                Character toon = new Character();
                toon.AccountID = acctId;
                toon.Name = name;
                toon.CreatedDate = DateTime.Now;
                dbCtx.Characters.InsertOnSubmit(toon);
                dbCtx.SubmitChanges();
            }

            return true;
        }
Esempio n. 12
0
        internal static bool Delete(string charName)
        {
            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                Data.Character charToDel = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
                if (charToDel != null)
                {
                    dbCtx.Characters.DeleteOnSubmit(charToDel);
                    dbCtx.SubmitChanges();
                    return true;
                }
            }

            return false;
        }
Esempio n. 13
0
        internal static void Create(string charName, CharacterCreate charCreateStruct)
        {
            // TODO: old emu does some in depth validation of race/class combinations and ability scores.  Will add later if necessary

            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                DataLoadOptions dlo = new DataLoadOptions();
                dlo.LoadWith<StartingItem>(si => si.Item);
                dbCtx.LoadOptions = dlo;

                Character toon = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
                toon.Race = (short)charCreateStruct.Race;
                toon.Class = (byte)charCreateStruct.Class;
                toon.Gender = (byte)charCreateStruct.Gender;
                toon.Deity = (int)charCreateStruct.Deity;
                toon.STR = (short)charCreateStruct.STR;
                toon.STA = (short)charCreateStruct.STA;
                toon.AGI = (short)charCreateStruct.AGI;
                toon.DEX = (short)charCreateStruct.DEX;
                toon.WIS = (short)charCreateStruct.WIS;
                toon.INT = (short)charCreateStruct.INT;
                toon.CHA = (short)charCreateStruct.CHA;
                toon.Face = (byte)charCreateStruct.Face;
                toon.EyeColor1 = (byte)charCreateStruct.EyeColor1;
                toon.EyeColor2 = (byte)charCreateStruct.EyeColor2;
                toon.HairStyle = (byte)charCreateStruct.HairStyle;
                toon.HairColor = (byte)charCreateStruct.HairColor;
                toon.Beard = (byte)charCreateStruct.Beard;
                toon.BeardColor = (byte)charCreateStruct.BeardColor;
                toon.LastSeenDate = DateTime.Now;
                toon.CharLevel = 1;
                toon.PracticePoints = 5;
                toon.HP = 1000;     // just here for dev, later will be set elsewhere
                toon.HungerLevel = 6000;
                toon.ThirstLevel = 6000;
                toon.Platinum = (uint)EQEmulator.Servers.WorldServer.ServerConfig.StartingPlat;
                toon.Gold = (uint)EQEmulator.Servers.WorldServer.ServerConfig.StartingGold;

                SetRacialStartingAbilities(ref toon);   // Sets languages and skills that are racially determined
                SetClassStartingAbilities(ref toon);    // Sets skills determined by class

                // Get the character's start zone
                StartZone startZone = dbCtx.StartZones.SingleOrDefault(sz => sz.PlayerChoice == charCreateStruct.StartZone
                    && sz.PlayerClass == charCreateStruct.Class && sz.PlayerDeity == charCreateStruct.Deity && sz.PlayerRace == charCreateStruct.Race);
                CharacterBind cb = new CharacterBind();
                toon.X = toon.Y = toon.Z = 0.0F;
                cb.X = cb.Y = cb.Z = 0.0F;
                toon.Heading = 0.0F;

                if (startZone != null)  // TODO: should heading for zone and bind be set to some default setting?
                {
                    // Found a start zone in the db... load up the bind info from that
                    toon.ZoneID = startZone.ZoneID;
                    toon.ZoneName = startZone.Zone.ShortName;
                    toon.X = startZone.X;
                    toon.Y = startZone.Y;
                    toon.Z = startZone.Z;

                    if (startZone.BindZoneID != null)
                    {
                        cb.ZoneID = startZone.BindZoneID.Value;
                        cb.X = startZone.BindX.Value;
                        cb.Y = startZone.BindY.Value;
                        cb.Z = startZone.BindZ.Value;
                    }
                    else
                        cb.ZoneID = startZone.ZoneID;
                }
                else
                    SetDefaultStartZone(charCreateStruct.StartZone, ref toon, ref cb);

                Zone zone = null;

                // Load safe points for start zone coords if necessary
                if (toon.X == 0.0F && toon.Y == 0.0F && toon.Z == 0.0F)
                {
                    zone = dbCtx.Zones.SingleOrDefault(z => z.ZoneID == toon.ZoneID);
                    toon.X = zone.SafeX;
                    toon.Y = zone.SafeY;
                    toon.Z = zone.SafeZ;
                }

                // Load safe points for start bind coords if necessary
                if (cb.X == 0.0F && cb.Y == 0.0F && cb.Z == 0.0F)
                {
                    zone = dbCtx.Zones.SingleOrDefault(z => z.ZoneID == cb.ZoneID);
                    if (zone != null)
                    {
                        cb.X = zone.SafeX;
                        cb.Y = zone.SafeY;
                        cb.Z = zone.SafeZ;
                    }
                    else
                        _log.ErrorFormat("Unable to load safe points for bind zone {0}", cb.ZoneID);
                }

                cb.Heading = toon.Heading.Value;
                toon.CharacterBinds.Add(cb);

                // Get starting items
                var startingItems = from si in dbCtx.StartingItems
                                    where (si.Race == toon.Race.Value || si.Race == 0) && (si.Class == toon.Class.Value || si.Class == 0)
                                    && (si.DeityID == (toon.Deity ?? 0) || si.DeityID == 0) && (si.ZoneID == toon.ZoneID.Value || si.ZoneID == 0)
                                    select si;

                int siSlotId = 22;    // for initial items with unspecified slots, just dump them to the personal inv slots
                foreach (StartingItem si in startingItems) {
                    InventoryItem ii = new InventoryItem {
                        ItemID = si.ItemID,
                        Charges = si.ItemCharges,
                        Color = si.Item.Color ?? 0,
                        SlotID = si.Slot
                    };

                    if (ii.SlotID < 0) {  // for unspecified inventory slots, find an open slot
                        ii.SlotID = siSlotId;
                        siSlotId++;
                    }

                    toon.InventoryItems.Add(ii);
                }

                dbCtx.SubmitChanges();
            }
        }
Esempio n. 14
0
        internal static bool CheckNameFilter(string name)
        {
            if (!Regex.IsMatch(name, @"^[a-zA-Z\'\s]{4,64}"))    // all alpha, between 4 and 64 in len
                return false;

            using (EmuDataContext dbCtx = new EmuDataContext())
                if (dbCtx.NameFilters.Count(nf => SqlMethods.Like(name, nf.Filter)) > 0)
                    return false;

            return true;
        }
Esempio n. 15
0
        internal void LoadGrid(int zoneId, EmuDataContext dbCtx)
        {
            if (_gridId < 1)
                return;

            //_log.DebugFormat("Loading grid {0} for {1}", _gridId, _name);

            Grid grid = dbCtx.Grids.SingleOrDefault(g => g.GridID == _gridId && g.ZoneID == zoneId);

            if (grid == null)
            {
                _log.WarnFormat("Unable to locate grid {0} in db for {1}... why does it have a non-zero grid id?", _gridId, this.Name);
                return;
            }

            _wanderType = grid.WanderType;
            _pauseType = grid.PauseType;

            var ges = from ge in dbCtx.GridEntries
                      where ge.GridID == _gridId && ge.ZoneID == zoneId
                      orderby ge.Ordinal
                      select new { Ordinal = ge.Ordinal, X = ge.X, Y = ge.Y, Z = ge.Z, Pause = ge.Pause };

            //_log.DebugFormat("Found {0} grid entries - creating that many waypoints.", ges.Count());
            _waypoints = new SortedList<int, Waypoint>(ges.Count());
            foreach (var ge in ges)     // TODO: may need some code for sending midair waypoints to the ground
                _waypoints.Add(ge.Ordinal, new Waypoint(ge.X, ge.Y, ge.Z, ge.Pause));

            if (_waypoints.Count > 1)
            {
                //_log.Debug("Minimum waypoint found was " + _waypoints.Keys.Min());
                UpdateWaypoint(_waypoints.Keys.Min());
                PauseAtWaypoint();
                SendTo(_curWaypoint.X, _curWaypoint.Y, _curWaypoint.Z);
                if (_wanderType == 1 || _wanderType == 2)
                    CalculateNewWaypoint();
            }
        }
Esempio n. 16
0
        //[TestMethod()]
        public void Inventory_Should_Have_Item_In_Correct_Spot_After_Moving_A_Container()
        {
            // ARRANGE
            // Get the client's character info
            string charName = "Littlebadwiz";
            Character toon = null;
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Character>(c => c.Account);
            dlo.LoadWith<Character>(c => c.Zone);
            dlo.LoadWith<Character>(c => c.InventoryItems);
            dlo.LoadWith<InventoryItem>(ii => ii.Item);

            using (EmuDataContext dbCtx = new EmuDataContext()) {
                dbCtx.ObjectTrackingEnabled = false;
                dbCtx.LoadOptions = dlo;
                toon = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
            }

            ZonePlayer zp = new ZonePlayer(1, toon, 1, new Client(new System.Net.IPEndPoint(0x2414188f, 123)));
            List<uint?> itemsBefore = new List<uint?> { null, null, null, null, null, null, null, null, null, null };
            List<uint?> itemsAfter = new List<uint?> { null, null, null, null, null, null, null, null, null, null };

            for (int i = 321; i < 331; i++) {   // track the original item ids
                if (zp.InvMgr[i] != null)
                    itemsBefore[i - 321] = zp.InvMgr[i].ItemID;
            }

            // ACT
            zp.InvMgr.SwapItem(29, 30, (byte)0);    // swap a container in the 8th inv slot to the cursor
            zp.InvMgr.SwapItem(30, 26, (byte)0);    // then swap the container from the cursor to the 5th inv slot

            for (int i = 291; i < 301; i++) {   // now track the current item ids
                if (zp.InvMgr[i] != null)
                    itemsAfter[i - 291] = zp.InvMgr[i].ItemID;
            }

            // ASSERT
            for (int i = 0; i < 10; i++)
                Assert.IsTrue(itemsBefore[i] == itemsAfter[i]);
        }
Esempio n. 17
0
        /// <summary>Persists all player data to the database. Thread safe. Call in a background thread if the save isn't needed immediately.</summary>
        /// <returns>True if successful, else false.</returns>
        internal override void Save()
        {
            lock (_saveLock) {
                using (EmuDataContext dbCtx = new EmuDataContext()) {
                    DataLoadOptions dlo = new DataLoadOptions();
                    dlo.LoadWith<Character>(c => c.InventoryItems);
                    dbCtx.LoadOptions = dlo;
                    //dbCtx.Log = new Log4NetWriter(typeof(ZonePlayer));

                    Character toon = dbCtx.Characters.SingleOrDefault(c => c.Name == this.Name);
                    toon.X = this.X;
                    toon.Y = this.Y;
                    toon.Z = this.Z;
                    toon.Heading = this.Heading;
                    toon.ZoneID = this.ZoneId;
                    toon.LastSeenDate = DateTime.Now;
                    toon.Platinum = this.Platinum;
                    toon.Gold = this.Gold;
                    toon.Silver = this.Silver;
                    toon.Copper = this.Copper;
                    toon.XP = _pp.XP;   // Going direct to the pp eliminates a cast
                    toon.CharLevel = this.Level;
                    toon.HP = this.HP;

                    // Convert skill values from the uint[] to a byte[]
                    byte[] skills = new byte[toon.Skills.Length];
                    for (int i = 0; i < _pp.Skills.Length; i++)
                        skills[i] = (byte)_pp.Skills[i];
                    toon.Skills = Encoding.ASCII.GetString(skills);

                    // Clear and then re-add the inventory, spellbook, mem'd spells (got a better idea?)
                    dbCtx.InventoryItems.DeleteAllOnSubmit(toon.InventoryItems);    // TODO: this gens many DELETE statements... could be improved
                    dbCtx.MemorizedSpells.DeleteAllOnSubmit(toon.MemorizedSpells);
                    dbCtx.ScribedSpells.DeleteAllOnSubmit(toon.ScribedSpells);
                    dbCtx.SubmitChanges();

                    foreach (InventoryItem invItem in this.InvMgr.AllItems()) {
                        //_log.DebugFormat("During save found item {0} in slot {1}", invItem.Item.Name, invItem.SlotID);
                        toon.InventoryItems.Add(invItem.ShallowCopy());
                    }

                    // Save spellbook
                    for (short i = 0; i < this.PlayerProfile.SpellBook.Length; i++) {
                        if (this.PlayerProfile.SpellBook[i] != Spell.BLANK_SPELL)   // Don't save blank spells
                            toon.ScribedSpells.Add(new ScribedSpell() { SlotID = i, SpellID = (ushort)this.PlayerProfile.SpellBook[i] });
                    }

                    // Save memorized spells
                    for (byte i = 0; i < this.PlayerProfile.MemSpells.Length; i++) {
                        if (this.PlayerProfile.MemSpells[i] != Spell.BLANK_SPELL)   // Don't save blank spells
                            toon.MemorizedSpells.Add(new MemorizedSpell() { SlotID = i, SpellID = (ushort)this.PlayerProfile.MemSpells[i] });
                    }

                    dbCtx.SubmitChanges();

                    // TODO: save cursor items
                }
            }

            _log.DebugFormat("{0} Saved.", this.Name);
        }
Esempio n. 18
0
        /// <summary>Initializes all data for a zone - spawns, zone points, AA, etc.</summary>
        private bool Init(ushort zoneId, ZoneInstanceType ziType)
        {
            // Load the zone along with associated zone points, spawns, spawn groups, spawn group entries and NPCs.
            // TODO: Probably will want to load this differently when zone state persistance is in (join to a state table for spawns?)
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Zone>(z => z.ZonePoints);
            dlo.LoadWith<Zone>(z => z.Doors);
            dlo.LoadWith<Zone>(z => z.Spawns);
            dlo.LoadWith<Internals.Data.Spawn>(s => s.SpawnGroup);
            dlo.LoadWith<SpawnGroup>(sg => sg.SpawnGroupEntries);
            dlo.AssociateWith<SpawnGroup>(sg => sg.SpawnGroupEntries.OrderBy(sge => sge.Chance));   // sort the spawnGroupEntries by chance
            dlo.LoadWith<SpawnGroupEntry>(sge => sge.Npc);
            dlo.LoadWith<Npc>(npc => npc.Loot);
            dlo.LoadWith<Loot>(l => l.LootEntries);
            dlo.LoadWith<LootEntry>(le => le.LootDrops);
            dlo.LoadWith<LootDrop>(ld => ld.Item);  // TODO: can we trim how much of an item comes back?

            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                dbCtx.ObjectTrackingEnabled = false;    // only loading referential data
                dbCtx.LoadOptions = dlo;    // TODO: use profiler to make sure we get it all in one call
                //dbCtx.Log = new Log4NetWriter(typeof(ZoneServer));
                _zone = dbCtx.Zones.Single(z => z.ZoneID == zoneId);
            }

            this.Zone.InitNewZoneStruct();
            _instanceType = ziType;

            // Load map & water map
            _map = new Map();
            _waterMap = new WaterMap();
            try
            {
                if (!_map.LoadMapFromFile(_zone.ShortName))
                    return false;

                if (!_waterMap.LoadMapFromFile(_zone.ShortName))
                    _waterMap = null;
            }
            catch (Exception e)
            {
                _log.Error("Error during map loading", e);
            }

            _mobMgr.Init();     // Must be done prior to any doors, mobs or player init

            if (_zone.Doors.Count > 0)
            {
                foreach (Door d in _zone.Doors)
                    d.EntityId = GetNewEntityId();  // Assign each door an entity Id

                _log.InfoFormat("Loaded {0} doors", _zone.Doors.Count);
            }
            else
                _log.Warn("No doors loaded");

            // TODO: Load Spawn Conditions

            SpawnTimerCallback(null);   // Load spawns NOW
            _log.InfoFormat("Loaded {0} Spawn", _mobMgr.MobCount);

            // TODO: Implement zone state persistance

            // TODO: Load corpses

            // TODO: Load traps

            // TODO: Load ground spawns

            // TODO: Load objects (tradeskill containers, maybe books, etc.)

            _maxSpellId = WorldSvc.GetMaxSpellId();
            if (_maxSpellId == 0)
                _log.Error("Max SpellId equals zero.  Problem with spell loading in world?");

            // TODO: Load blocked spells

            // TODO: Load guilds, factions, titles, AA, Tributes, corpse timers?

            // TODO: Load merchant data

            // TODO: Load petition data

            // TODO: Load graveyard

            // TODO: Load timezone data

            // TODO: Implement server time keeping in world and then sync up here (see end of orig Init and bootup routines)

            // Just before we finish, start up the various timers
            _spawnTimer.Change(30000, SPAWN_TIMER_INTERVAL);    // We've already populated the spawn list, so wait a bit
            _spawnQueueTimer.Change(5000, SPAWN_QUEUE_TIMER_INTERVAL);  // wait 5 sec before worrying about queued spawn packets
            _doorTimer.Change(10000, DOOR_TIMER_INTERVAL);  // wait 10 sec before worrying about doors

            // Initialize weather timer
            if (_zone.Weather <= 3 && _zone.Weather > 0)
            {
                Random rand = new Random();
                _weatherTimer.Change(0, (rand.Next(1800, 7200) + 30) * 2000);
            }

            return true;
        }