Beispiel #1
0
        public void LoadFromDB()
        {
            // Pool templates
            {
                uint oldMSTime = Time.GetMSTime();

                SQLResult result = DB.World.Query("SELECT entry, max_limit FROM pool_template");
                if (result.IsEmpty())
                {
                    mPoolTemplate.Clear();
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 object pools. DB table `pool_template` is empty.");
                    return;
                }

                uint count = 0;
                do
                {
                    uint pool_id = result.Read <uint>(0);

                    PoolTemplateData pPoolTemplate = new PoolTemplateData();
                    pPoolTemplate.MaxLimit = result.Read <uint>(1);
                    mPoolTemplate[pool_id] = pPoolTemplate;
                    ++count;
                }while (result.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} objects pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
            }

            // Creatures

            Log.outInfo(LogFilter.ServerLoading, "Loading Creatures Pooling Data...");
            {
                uint oldMSTime = Time.GetMSTime();

                //                                                 1       2         3
                SQLResult result = DB.World.Query("SELECT guid, pool_entry, chance FROM pool_creature");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 creatures in  pools. DB table `pool_creature` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        ulong guid    = result.Read <ulong>(0);
                        uint  pool_id = result.Read <uint>(1);
                        float chance  = result.Read <float>(2);

                        CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
                        if (data == null)
                        {
                            Log.outError(LogFilter.Sql, "`pool_creature` has a non existing creature spawn (GUID: {0}) defined for pool id ({1}), skipped.", guid, pool_id);
                            continue;
                        }
                        if (!mPoolTemplate.ContainsKey(pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_creature` pool id ({0}) is not in `pool_template`, skipped.", pool_id);
                            continue;
                        }
                        if (chance < 0 || chance > 100)
                        {
                            Log.outError(LogFilter.Sql, "`pool_creature` has an invalid chance ({0}) for creature guid ({1}) in pool id ({2}), skipped.", chance, guid, pool_id);
                            continue;
                        }
                        PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id];
                        PoolObject       plObject      = new PoolObject(guid, chance);

                        if (!mPoolCreatureGroups.ContainsKey(pool_id))
                        {
                            mPoolCreatureGroups[pool_id] = new PoolGroup <Creature>();
                        }

                        PoolGroup <Creature> cregroup = mPoolCreatureGroups[pool_id];
                        cregroup.SetPoolId(pool_id);
                        cregroup.AddEntry(plObject, pPoolTemplate.MaxLimit);

                        mCreatureSearchMap.Add(guid, pool_id);
                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creatures in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // Gameobjects

            Log.outInfo(LogFilter.ServerLoading, "Loading Gameobject Pooling Data...");
            {
                uint oldMSTime = Time.GetMSTime();

                //                                                 1        2         3
                SQLResult result = DB.World.Query("SELECT guid, pool_entry, chance FROM pool_gameobject");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 gameobjects in  pools. DB table `pool_gameobject` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        ulong guid    = result.Read <ulong>(0);
                        uint  pool_id = result.Read <uint>(1);
                        float chance  = result.Read <float>(2);

                        GameObjectData data = Global.ObjectMgr.GetGOData(guid);
                        if (data == null)
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` has a non existing gameobject spawn (GUID: {0}) defined for pool id ({1}), skipped.", guid, pool_id);
                            continue;
                        }

                        GameObjectTemplate goinfo = Global.ObjectMgr.GetGameObjectTemplate(data.id);
                        if (goinfo.type != GameObjectTypes.Chest &&
                            goinfo.type != GameObjectTypes.FishingHole &&
                            goinfo.type != GameObjectTypes.GatheringNode &&
                            goinfo.type != GameObjectTypes.Goober)
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` has a not lootable gameobject spawn (GUID: {0}, type: {1}) defined for pool id ({2}), skipped.", guid, goinfo.type, pool_id);
                            continue;
                        }

                        if (!mPoolTemplate.ContainsKey(pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` pool id ({0}) is not in `pool_template`, skipped.", pool_id);
                            continue;
                        }

                        if (chance < 0 || chance > 100)
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` has an invalid chance ({0}) for gameobject guid ({1}) in pool id ({2}), skipped.", chance, guid, pool_id);
                            continue;
                        }

                        PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id];
                        PoolObject       plObject      = new PoolObject(guid, chance);

                        if (!mPoolGameobjectGroups.ContainsKey(pool_id))
                        {
                            mPoolGameobjectGroups[pool_id] = new PoolGroup <GameObject>();
                        }

                        PoolGroup <GameObject> gogroup = mPoolGameobjectGroups[pool_id];
                        gogroup.SetPoolId(pool_id);
                        gogroup.AddEntry(plObject, pPoolTemplate.MaxLimit);

                        mGameobjectSearchMap.Add(guid, pool_id);
                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} gameobject in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // Pool of pools

            Log.outInfo(LogFilter.ServerLoading, "Loading Mother Pooling Data...");
            {
                uint oldMSTime = Time.GetMSTime();

                //                                                  1        2            3
                SQLResult result = DB.World.Query("SELECT pool_id, mother_pool, chance FROM pool_pool");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 pools in pools");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  child_pool_id  = result.Read <uint>(0);
                        uint  mother_pool_id = result.Read <uint>(1);
                        float chance         = result.Read <float>(2);

                        if (!mPoolTemplate.ContainsKey(mother_pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` mother_pool id ({0}) is not in `pool_template`, skipped.", mother_pool_id);
                            continue;
                        }
                        if (!mPoolTemplate.ContainsKey(child_pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` included pool_id ({0}) is not in `pool_template`, skipped.", child_pool_id);
                            continue;
                        }
                        if (mother_pool_id == child_pool_id)
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` pool_id ({0}) includes itself, dead-lock detected, skipped.", child_pool_id);
                            continue;
                        }
                        if (chance < 0 || chance > 100)
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` has an invalid chance ({0}) for pool id ({1}) in mother pool id ({2}), skipped.", chance, child_pool_id, mother_pool_id);
                            continue;
                        }
                        PoolTemplateData pPoolTemplateMother = mPoolTemplate[mother_pool_id];
                        PoolObject       plObject            = new PoolObject(child_pool_id, chance);

                        if (!mPoolPoolGroups.ContainsKey(mother_pool_id))
                        {
                            mPoolPoolGroups[mother_pool_id] = new PoolGroup <Pool>();
                        }

                        PoolGroup <Pool> plgroup = mPoolPoolGroups[mother_pool_id];
                        plgroup.SetPoolId(mother_pool_id);
                        plgroup.AddEntry(plObject, pPoolTemplateMother.MaxLimit);

                        mPoolSearchMap.Add(child_pool_id, mother_pool_id);
                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} pools in mother pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            Log.outInfo(LogFilter.ServerLoading, "Loading Quest Pooling Data...");
            {
                uint oldMSTime = Time.GetMSTime();

                PreparedStatement stmt   = DB.World.GetPreparedStatement(WorldStatements.SEL_QUEST_POOLS);
                SQLResult         result = DB.World.Query(stmt);

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 quests in pools");
                }
                else
                {
                    List <uint> creBounds;
                    List <uint> goBounds;

                    Dictionary <uint, QuestTypes> poolTypeMap = new Dictionary <uint, QuestTypes>();
                    uint count = 0;
                    do
                    {
                        uint entry   = result.Read <uint>(0);
                        uint pool_id = result.Read <uint>(1);

                        if (!poolTypeMap.ContainsKey(pool_id))
                        {
                            poolTypeMap[pool_id] = 0;
                        }

                        Quest quest = Global.ObjectMgr.GetQuestTemplate(entry);
                        if (quest == null)
                        {
                            Log.outError(LogFilter.Sql, "`pool_quest` has a non existing quest template (Entry: {0}) defined for pool id ({1}), skipped.", entry, pool_id);
                            continue;
                        }

                        if (!mPoolTemplate.ContainsKey(pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_quest` pool id ({0}) is not in `pool_template`, skipped.", pool_id);
                            continue;
                        }

                        if (!quest.IsDailyOrWeekly())
                        {
                            Log.outError(LogFilter.Sql, "`pool_quest` has an quest ({0}) which is not daily or weekly in pool id ({1}), use ExclusiveGroup instead, skipped.", entry, pool_id);
                            continue;
                        }

                        if (poolTypeMap[pool_id] == QuestTypes.None)
                        {
                            poolTypeMap[pool_id] = quest.IsDaily() ? QuestTypes.Daily : QuestTypes.Weekly;
                        }

                        QuestTypes currType = quest.IsDaily() ? QuestTypes.Daily : QuestTypes.Weekly;

                        if (poolTypeMap[pool_id] != currType)
                        {
                            Log.outError(LogFilter.Sql, "`pool_quest` quest {0} is {1} but pool ({2}) is specified for {3}, mixing not allowed, skipped.",
                                         entry, currType, pool_id, poolTypeMap[pool_id]);
                            continue;
                        }

                        creBounds = mQuestCreatureRelation.LookupByKey(entry);
                        goBounds  = mQuestGORelation.LookupByKey(entry);

                        if (creBounds.Empty() && goBounds.Empty())
                        {
                            Log.outError(LogFilter.Sql, "`pool_quest` lists entry ({0}) as member of pool ({1}) but is not started anywhere, skipped.", entry, pool_id);
                            continue;
                        }

                        PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id];
                        PoolObject       plObject      = new PoolObject(entry, 0.0f);

                        if (!mPoolQuestGroups.ContainsKey(pool_id))
                        {
                            mPoolQuestGroups[pool_id] = new PoolGroup <Quest>();
                        }

                        PoolGroup <Quest> questgroup = mPoolQuestGroups[pool_id];
                        questgroup.SetPoolId(pool_id);
                        questgroup.AddEntry(plObject, pPoolTemplate.MaxLimit);

                        mQuestSearchMap.Add(entry, pool_id);
                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} quests in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks
            Log.outInfo(LogFilter.ServerLoading, "Starting objects pooling system...");
            {
                uint oldMSTime = Time.GetMSTime();

                SQLResult result = DB.World.Query("SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template" +
                                                  " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry" +
                                                  " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Pool handling system initialized, 0 pools spawned.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint pool_entry   = result.Read <uint>(0);
                        uint pool_pool_id = result.Read <uint>(1);

                        if (!CheckPool(pool_entry))
                        {
                            if (pool_pool_id != 0)
                            {
                                // The pool is a child pool in pool_pool table. Ideally we should remove it from the pool handler to ensure it never gets spawned,
                                // however that could recursively invalidate entire chain of mother pools. It can be done in the future but for now we'll do nothing.
                                Log.outError(LogFilter.Sql, "Pool Id {0} has no equal chance pooled entites defined and explicit chance sum is not 100. This broken pool is a child pool of Id {1} and cannot be safely removed.", pool_entry, result.Read <uint>(2));
                            }
                            else
                            {
                                Log.outError(LogFilter.Sql, "Pool Id {0} has no equal chance pooled entites defined and explicit chance sum is not 100. The pool will not be spawned.", pool_entry);
                            }
                            continue;
                        }

                        // Don't spawn child pools, they are spawned recursively by their parent pools
                        if (pool_pool_id == 0)
                        {
                            SpawnPool(pool_entry);
                            count++;
                        }
                    }while (result.NextRow());

                    Log.outDebug(LogFilter.Pool, "Pool handling system initialized, {0} pools spawned in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }
        }
Beispiel #2
0
        public void LoadWardenChecks()
        {
            uint oldMSTime = Time.GetMSTime();

            // Check if Warden is enabled by config before loading anything
            if (!WorldConfig.GetBoolValue(WorldCfg.WardenEnabled))
            {
                Log.outInfo(LogFilter.Warden, "Warden disabled, loading checks skipped.");
                return;
            }

            //                              0    1     2     3        4       5      6      7
            SQLResult result = DB.World.Query("SELECT id, type, data, result, address, length, str, comment FROM warden_checks ORDER BY id ASC");

            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 Warden checks. DB table `warden_checks` is empty!");
                return;
            }

            uint count = 0;

            do
            {
                ushort          id          = result.Read <ushort>(0);
                WardenCheckType checkType   = (WardenCheckType)result.Read <byte>(1);
                string          data        = result.Read <string>(2);
                string          checkResult = result.Read <string>(3);
                uint            address     = result.Read <uint>(4);
                byte            length      = result.Read <byte>(5);
                string          str         = result.Read <string>(6);
                string          comment     = result.Read <string>(7);

                WardenCheck wardenCheck = new();
                wardenCheck.Type    = checkType;
                wardenCheck.CheckId = id;

                // Initialize action with default action from config
                wardenCheck.Action = (WardenActions)WorldConfig.GetIntValue(WorldCfg.WardenClientFailAction);

                if (checkType == WardenCheckType.PageA || checkType == WardenCheckType.PageB || checkType == WardenCheckType.Driver)
                {
                    wardenCheck.Data = new BigInteger(data.ToByteArray());
                }

                if (checkType == WardenCheckType.Memory || checkType == WardenCheckType.Module)
                {
                    MemChecksIdPool.Add(id);
                }
                else
                {
                    OtherChecksIdPool.Add(id);
                }

                if (checkType == WardenCheckType.Memory || checkType == WardenCheckType.PageA || checkType == WardenCheckType.PageB || checkType == WardenCheckType.Proc)
                {
                    wardenCheck.Address = address;
                    wardenCheck.Length  = length;
                }

                // PROC_CHECK support missing
                if (checkType == WardenCheckType.Memory || checkType == WardenCheckType.MPQ || checkType == WardenCheckType.LuaStr || checkType == WardenCheckType.Driver || checkType == WardenCheckType.Module)
                {
                    wardenCheck.Str = str;
                }

                CheckStore[id] = wardenCheck;

                if (checkType == WardenCheckType.MPQ || checkType == WardenCheckType.Memory)
                {
                    BigInteger Result = new(checkResult.ToByteArray());
                    CheckResultStore[id] = Result;
                }

                if (comment.IsEmpty())
                {
                    wardenCheck.Comment = "Undocumented Check";
                }
                else
                {
                    wardenCheck.Comment = comment;
                }

                ++count;
            }while (result.NextRow());

            Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} warden checks in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
        }
Beispiel #3
0
        public void LoadGuilds()
        {
            Log.outInfo(LogFilter.ServerLoading, "Loading Guilds Definitions...");
            {
                uint oldMSTime = Time.GetMSTime();

                //          0          1       2             3              4              5              6
                SQLResult result = DB.Characters.Query("SELECT g.guildid, g.name, g.leaderguid, g.EmblemStyle, g.EmblemColor, g.BorderStyle, g.BorderColor, " +
                                                       //   7                  8       9       10            11          12
                                                       "g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, COUNT(gbt.guildid) " +
                                                       "FROM guild g LEFT JOIN guild_bank_tab gbt ON g.guildid = gbt.guildid GROUP BY g.guildid ORDER BY g.guildid ASC");

                if (result.IsEmpty())
                {
                    Log.outError(LogFilter.Guild, "Loaded 0 guild definitions. DB table `guild` is empty.");
                    return;
                }

                uint count = 0;
                do
                {
                    Guild guild = new Guild();

                    if (!guild.LoadFromDB(result.GetFields()))
                    {
                        continue;
                    }

                    AddGuild(guild);
                    count++;
                } while (result.NextRow());
                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild definitions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
            }

            Log.outInfo(LogFilter.ServerLoading, "Loading guild ranks...");
            {
                uint oldMSTime = Time.GetMSTime();

                // Delete orphaned guild rank entries before loading the valid ones
                DB.Characters.DirectExecute("DELETE gr FROM guild_rank gr LEFT JOIN guild g ON gr.guildId = g.guildId WHERE g.guildId IS NULL");

                //                                                   0    1      2       3                4
                SQLResult result = DB.Characters.Query("SELECT guildid, rid, rname, rights, BankMoneyPerDay FROM guild_rank ORDER BY guildid ASC, rid ASC");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild ranks. DB table `guild_rank` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  guildId = result.Read <uint>(0);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadRankFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild ranks in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 3. Load all guild members
            Log.outInfo(LogFilter.ServerLoading, "Loading guild members...");
            {
                uint oldMSTime = Time.GetMSTime();

                // Delete orphaned guild member entries before loading the valid ones
                DB.Characters.DirectExecute("DELETE gm FROM guild_member gm LEFT JOIN guild g ON gm.guildId = g.guildId WHERE g.guildId IS NULL");
                DB.Characters.DirectExecute("DELETE gm FROM guild_member_withdraw gm LEFT JOIN guild_member g ON gm.guid = g.guid WHERE g.guid IS NULL");

                //           0           1        2     3      4        5       6       7       8       9       10
                SQLResult result = DB.Characters.Query("SELECT gm.guildid, gm.guid, rank, pnote, offnote, w.tab0, w.tab1, w.tab2, w.tab3, w.tab4, w.tab5, " +
                                                       //   11      12      13       14      15       16       17      18         19         20
                                                       "w.tab6, w.tab7, w.money, c.name, c.level, c.class, c.gender, c.zone, c.account, c.logout_time " +
                                                       "FROM guild_member gm LEFT JOIN guild_member_withdraw w ON gm.guid = w.guid " +
                                                       "LEFT JOIN characters c ON c.guid = gm.guid ORDER BY gm.guildid ASC");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild members. DB table `guild_member` is empty.");
                }
                else
                {
                    uint count = 0;

                    do
                    {
                        uint  guildId = result.Read <uint>(0);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadMemberFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild members in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 4. Load all guild bank tab rights
            Log.outInfo(LogFilter.ServerLoading, "Loading bank tab rights...");
            {
                uint oldMSTime = Time.GetMSTime();

                // Delete orphaned guild bank right entries before loading the valid ones
                DB.Characters.DirectExecute("DELETE gbr FROM guild_bank_right gbr LEFT JOIN guild g ON gbr.guildId = g.guildId WHERE g.guildId IS NULL");

                //      0        1      2    3        4
                SQLResult result = DB.Characters.Query("SELECT guildid, TabId, rid, gbright, SlotPerDay FROM guild_bank_right ORDER BY guildid ASC, TabId ASC");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild bank tab rights. DB table `guild_bank_right` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  guildId = result.Read <uint>(0);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadBankRightFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} bank tab rights in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 5. Load all event logs
            Log.outInfo(LogFilter.ServerLoading, "Loading guild event logs...");
            {
                uint oldMSTime = Time.GetMSTime();

                DB.Characters.DirectExecute("DELETE FROM guild_eventlog WHERE LogGuid > {0}", GuildConst.EventLogMaxRecords);

                //          0        1        2          3            4            5        6
                SQLResult result = DB.Characters.Query("SELECT guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp FROM guild_eventlog ORDER BY TimeStamp DESC, LogGuid DESC");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild event logs. DB table `guild_eventlog` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  guildId = result.Read <uint>(0);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadEventLogFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild event logs in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 6. Load all bank event logs
            Log.outInfo(LogFilter.ServerLoading, "Loading guild bank event logs...");
            {
                uint oldMSTime = Time.GetMSTime();

                // Remove log entries that exceed the number of allowed entries per guild
                DB.Characters.DirectExecute("DELETE FROM guild_bank_eventlog WHERE LogGuid > {0}", GuildConst.BankLogMaxRecords);

                //          0        1      2        3          4           5            6               7          8
                SQLResult result = DB.Characters.Query("SELECT guildid, TabId, LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog ORDER BY TimeStamp DESC, LogGuid DESC");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild bank event logs. DB table `guild_bank_eventlog` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  guildId = result.Read <uint>(0);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadBankEventLogFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild bank event logs in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 7. Load all news event logs
            Log.outInfo(LogFilter.ServerLoading, "Loading Guild News...");
            {
                uint oldMSTime = Time.GetMSTime();

                DB.Characters.DirectExecute("DELETE FROM guild_newslog WHERE LogGuid > {0}", GuildConst.NewsLogMaxRecords);

                //      0        1        2          3           4      5      6
                SQLResult result = DB.Characters.Query("SELECT guildid, LogGuid, EventType, PlayerGuid, Flags, Value, Timestamp FROM guild_newslog ORDER BY TimeStamp DESC, LogGuid DESC");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild event logs. DB table `guild_newslog` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  guildId = result.Read <uint>(0);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadGuildNewsLogFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild new logs in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 8. Load all guild bank tabs
            Log.outInfo(LogFilter.ServerLoading, "Loading guild bank tabs...");
            {
                uint oldMSTime = Time.GetMSTime();

                // Delete orphaned guild bank tab entries before loading the valid ones
                DB.Characters.DirectExecute("DELETE gbt FROM guild_bank_tab gbt LEFT JOIN guild g ON gbt.guildId = g.guildId WHERE g.guildId IS NULL");

                //         0        1      2        3        4
                SQLResult result = DB.Characters.Query("SELECT guildid, TabId, TabName, TabIcon, TabText FROM guild_bank_tab ORDER BY guildid ASC, TabId ASC");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild bank tabs. DB table `guild_bank_tab` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  guildId = result.Read <uint>(0);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadBankTabFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild bank tabs in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 9. Fill all guild bank tabs
            Log.outInfo(LogFilter.ServerLoading, "Filling bank tabs with items...");
            {
                uint oldMSTime = Time.GetMSTime();

                // Delete orphan guild bank items
                DB.Characters.DirectExecute("DELETE gbi FROM guild_bank_item gbi LEFT JOIN guild g ON gbi.guildId = g.guildId WHERE g.guildId IS NULL");

                SQLResult result = DB.Characters.Query(DB.Characters.GetPreparedStatement(CharStatements.SEL_GUILD_BANK_ITEMS));
                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 guild bank tab items. DB table `guild_bank_item` or `item_instance` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        ulong guildId = result.Read <ulong>(45);
                        Guild guild   = GetGuildById(guildId);
                        if (guild)
                        {
                            guild.LoadBankItemFromDB(result.GetFields());
                        }

                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} guild bank tab items in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // 10. Load guild achievements
            Log.outInfo(LogFilter.ServerLoading, "Loading guild achievements...");
            {
                uint oldMSTime = Time.GetMSTime();

                foreach (var pair in GuildStore)
                {
                    PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GUILD_ACHIEVEMENT);
                    stmt.AddValue(0, pair.Key);
                    SQLResult achievementResult = DB.Characters.Query(stmt);

                    stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GUILD_ACHIEVEMENT_CRITERIA);
                    stmt.AddValue(0, pair.Key);
                    SQLResult criteriaResult = DB.Characters.Query(stmt);

                    pair.Value.GetAchievementMgr().LoadFromDB(achievementResult, criteriaResult);
                }

                Log.outInfo(LogFilter.ServerLoading, "Loaded guild achievements and criterias in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
            }

            // 11. Validate loaded guild data
            Log.outInfo(LogFilter.Server, "Validating data of loaded guilds...");
            {
                uint oldMSTime = Time.GetMSTime();

                foreach (var guild in GuildStore.ToList())
                {
                    if (!guild.Value.Validate())
                    {
                        GuildStore.Remove(guild.Key);
                    }
                }

                Log.outInfo(LogFilter.ServerLoading, "Validated data of loaded guilds in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
            }
        }
        void HandleRequestBattlefieldStatus(RequestBattlefieldStatus packet)
        {
            // we must update all queues here
            Battleground bg = null;

            for (byte i = 0; i < SharedConst.MaxPlayerBGQueues; ++i)
            {
                BattlegroundQueueTypeId bgQueueTypeId = GetPlayer().GetBattlegroundQueueTypeId(i);
                if (bgQueueTypeId == 0)
                {
                    continue;
                }

                BattlegroundTypeId bgTypeId  = Global.BattlegroundMgr.BGTemplateId(bgQueueTypeId);
                ArenaTypes         arenaType = Global.BattlegroundMgr.BGArenaType(bgQueueTypeId);
                if (bgTypeId == GetPlayer().GetBattlegroundTypeId())
                {
                    bg = GetPlayer().GetBattleground();
                    //i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena
                    //so i must use bg pointer to get that information
                    if (bg && bg.GetArenaType() == arenaType)
                    {
                        BattlefieldStatusActive battlefieldStatus;
                        Global.BattlegroundMgr.BuildBattlegroundStatusActive(out battlefieldStatus, bg, GetPlayer(), i, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), arenaType);
                        SendPacket(battlefieldStatus);
                        continue;
                    }
                }

                //we are sending update to player about queue - he can be invited there!
                //get GroupQueueInfo for queue status
                BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId);
                GroupQueueInfo    ginfo;
                if (!bgQueue.GetPlayerGroupInfoData(GetPlayer().GetGUID(), out ginfo))
                {
                    continue;
                }

                if (ginfo.IsInvitedToBGInstanceGUID != 0)
                {
                    bg = Global.BattlegroundMgr.GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
                    if (!bg)
                    {
                        continue;
                    }

                    BattlefieldStatusNeedConfirmation battlefieldStatus;
                    Global.BattlegroundMgr.BuildBattlegroundStatusNeedConfirmation(out battlefieldStatus, bg, GetPlayer(), i, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), Time.GetMSTimeDiff(Time.GetMSTime(), ginfo.RemoveInviteTime), arenaType);
                    SendPacket(battlefieldStatus);
                }
                else
                {
                    bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId);
                    if (!bg)
                    {
                        continue;
                    }

                    // expected bracket entry
                    PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());
                    if (bracketEntry == null)
                    {
                        continue;
                    }

                    uint avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId());
                    BattlefieldStatusQueued battlefieldStatus;
                    Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatus, bg, GetPlayer(), i, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), avgTime, arenaType, ginfo.Players.Count > 1);
                    SendPacket(battlefieldStatus);
                }
            }
        }
Beispiel #5
0
        public void LoadCreatureTexts()
        {
            uint oldMSTime = Time.GetMSTime();

            mTextMap.Clear(); // for reload case
            //all currently used temp texts are NOT reset

            PreparedStatement stmt   = DB.World.GetPreparedStatement(WorldStatements.SEL_CREATURE_TEXT);
            SQLResult         result = DB.World.Query(stmt);

            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 ceature texts. DB table `creature_texts` is empty.");
                return;
            }

            uint textCount     = 0;
            uint creatureCount = 0;

            do
            {
                CreatureTextEntry temp = new CreatureTextEntry();

                temp.creatureId      = result.Read <uint>(0);
                temp.groupId         = result.Read <byte>(1);
                temp.id              = result.Read <byte>(2);
                temp.text            = result.Read <string>(3);
                temp.type            = (ChatMsg)result.Read <byte>(4);
                temp.lang            = (Language)result.Read <byte>(5);
                temp.probability     = result.Read <float>(6);
                temp.emote           = (Emote)result.Read <uint>(7);
                temp.duration        = result.Read <uint>(8);
                temp.sound           = result.Read <uint>(9);
                temp.BroadcastTextId = result.Read <uint>(10);
                temp.TextRange       = (CreatureTextRange)result.Read <byte>(11);

                if (temp.sound != 0)
                {
                    if (!CliDB.SoundKitStorage.ContainsKey(temp.sound))
                    {
                        Log.outError(LogFilter.Sql, "GossipManager:  Entry {0}, Group {1} in table `creature_texts` has Sound {2} but sound does not exist.", temp.creatureId, temp.groupId, temp.sound);
                        temp.sound = 0;
                    }
                }
                if (ObjectManager.GetLanguageDescByID(temp.lang) == null)
                {
                    Log.outError(LogFilter.Sql, "GossipManager:  Entry {0}, Group {1} in table `creature_texts` using Language {2} but Language does not exist.", temp.creatureId, temp.groupId, temp.lang);
                    temp.lang = Language.Universal;
                }
                if (temp.type >= ChatMsg.Max)
                {
                    Log.outError(LogFilter.Sql, "GossipManager:  Entry {0}, Group {1} in table `creature_texts` has Type {2} but this Chat Type does not exist.", temp.creatureId, temp.groupId, temp.type);
                    temp.type = ChatMsg.Say;
                }
                if (temp.emote != 0)
                {
                    if (!CliDB.EmotesStorage.ContainsKey((uint)temp.emote))
                    {
                        Log.outError(LogFilter.Sql, "GossipManager:  Entry {0}, Group {1} in table `creature_texts` has Emote {2} but emote does not exist.", temp.creatureId, temp.groupId, temp.emote);
                        temp.emote = Emote.OneshotNone;
                    }
                }

                if (temp.BroadcastTextId != 0)
                {
                    if (!CliDB.BroadcastTextStorage.ContainsKey(temp.BroadcastTextId))
                    {
                        Log.outError(LogFilter.Sql, "CreatureTextMgr: Entry {0}, Group {1}, Id {2} in table `creature_texts` has non-existing or incompatible BroadcastTextId {3}.", temp.creatureId, temp.groupId, temp.id, temp.BroadcastTextId);
                        temp.BroadcastTextId = 0;
                    }
                }

                if (temp.TextRange > CreatureTextRange.World)
                {
                    Log.outError(LogFilter.Sql, "CreatureTextMgr: Entry {0}, Group {1}, Id {2} in table `creature_text` has incorrect TextRange {3}.", temp.creatureId, temp.groupId, temp.id, temp.TextRange);
                    temp.TextRange = CreatureTextRange.Normal;
                }

                if (!mTextMap.ContainsKey(temp.creatureId))
                {
                    mTextMap[temp.creatureId] = new MultiMap <byte, CreatureTextEntry>();
                    ++creatureCount;
                }

                mTextMap[temp.creatureId].Add(temp.groupId, temp);
                ++textCount;
            } while (result.NextRow());

            Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creature texts for {1} creatures in {2} ms", textCount, creatureCount, Time.GetMSTimeDiffToNow(oldMSTime));
        }
Beispiel #6
0
        public void LoadRBAC()
        {
            ClearRBAC();

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC");
            uint oldMSTime = Time.GetMSTime();
            uint count1    = 0;
            uint count2    = 0;
            uint count3    = 0;

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading permissions");
            SQLResult result = DB.Login.Query("SELECT id, name FROM rbac_permissions");

            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 account permission definitions. DB table `rbac_permissions` is empty.");
                return;
            }

            do
            {
                uint id = result.Read <uint>(0);
                _permissions[id] = new RBACPermission(id, result.Read <string>(1));
                ++count1;
            }while (result.NextRow());

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading linked permissions");
            result = DB.Login.Query("SELECT id, linkedId FROM rbac_linked_permissions ORDER BY id ASC");
            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 linked permissions. DB table `rbac_linked_permissions` is empty.");
                return;
            }

            uint           permissionId = 0;
            RBACPermission permission   = null;

            do
            {
                uint newId = result.Read <uint>(0);
                if (permissionId != newId)
                {
                    permissionId = newId;
                    permission   = _permissions[newId];
                }

                uint linkedPermissionId = result.Read <uint>(1);
                if (linkedPermissionId == permissionId)
                {
                    Log.outError(LogFilter.Sql, "RBAC Permission {0} has itself as linked permission. Ignored", permissionId);
                    continue;
                }
                permission.AddLinkedPermission(linkedPermissionId);
                ++count2;
            }while (result.NextRow());

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading default permissions");
            result = DB.Login.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC");
            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
                return;
            }

            uint secId = 255;

            do
            {
                uint newId = result.Read <uint>(0);
                if (secId != newId)
                {
                    secId = newId;
                }

                _defaultPermissions.Add((byte)secId, result.Read <uint>(1));
                ++count3;
            }while (result.NextRow());

            Log.outInfo(LogFilter.ServerLoading, "Loaded {0} permission definitions, {1} linked permissions and {2} default permissions in {3} ms", count1, count2, count3, Time.GetMSTimeDiffToNow(oldMSTime));
        }
Beispiel #7
0
        public override void HandleData(ByteBuffer buff)
        {
            Log.outDebug(LogFilter.Warden, "Handle data");

            _dataSent            = false;
            _clientResponseTimer = 0;

            ushort Length   = buff.ReadUInt16();
            uint   Checksum = buff.ReadUInt32();

            if (!IsValidCheckSum(Checksum, buff.GetData(), Length))
            {
                Log.outWarn(LogFilter.Warden, "{0} failed checksum. Action: {1}", _session.GetPlayerInfo(), Penalty());
                return;
            }

            // TIMING_CHECK
            {
                byte result = buff.ReadUInt8();
                // @todo test it.
                if (result == 0x00)
                {
                    Log.outWarn(LogFilter.Warden, "{0} failed timing check. Action: {1}", _session.GetPlayerInfo(), Penalty());
                    return;
                }

                uint newClientTicks = buff.ReadUInt32();

                uint ticksNow = Time.GetMSTime();
                uint ourTicks = newClientTicks + (ticksNow - _serverTicks);

                Log.outDebug(LogFilter.Warden, "ServerTicks {0}", ticksNow);         // Now
                Log.outDebug(LogFilter.Warden, "RequestTicks {0}", _serverTicks);    // At request
                Log.outDebug(LogFilter.Warden, "Ticks {0}", newClientTicks);         // At response
                Log.outDebug(LogFilter.Warden, "Ticks diff {0}", ourTicks - newClientTicks);
            }

            BigInteger      rs;
            WardenCheck     rd;
            WardenCheckType type;
            ushort          checkFailed = 0;

            foreach (var id in _currentChecks)
            {
                rd = Global.WardenCheckMgr.GetWardenDataById(id);
                rs = Global.WardenCheckMgr.GetWardenResultById(id);

                type = rd.Type;
                switch (type)
                {
                case WardenCheckType.Memory:
                {
                    byte Mem_Result = buff.ReadUInt8();

                    if (Mem_Result != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MEM_CHECK not 0x00, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    if (buff.ReadBytes(rd.Length).Compare(rs.ToByteArray()))
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MEM_CHECK fail CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    Log.outDebug(LogFilter.Warden, "RESULT MEM_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    break;
                }

                case WardenCheckType.PageA:
                case WardenCheckType.PageB:
                case WardenCheckType.Driver:
                case WardenCheckType.Module:
                {
                    byte value = 0xE9;
                    if (buff.ReadUInt8() != value)
                    {
                        if (type == WardenCheckType.PageA || type == WardenCheckType.PageB)
                        {
                            Log.outDebug(LogFilter.Warden, "RESULT PAGE_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        }
                        if (type == WardenCheckType.Module)
                        {
                            Log.outDebug(LogFilter.Warden, "RESULT MODULE_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        }
                        if (type == WardenCheckType.Driver)
                        {
                            Log.outDebug(LogFilter.Warden, "RESULT DRIVER_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        }
                        checkFailed = id;
                        continue;
                    }

                    if (type == WardenCheckType.PageA || type == WardenCheckType.PageB)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT PAGE_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    }
                    else if (type == WardenCheckType.Module)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MODULE_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    }
                    else if (type == WardenCheckType.Driver)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT DRIVER_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    }
                    break;
                }

                case WardenCheckType.LuaStr:
                {
                    byte Lua_Result = buff.ReadUInt8();

                    if (Lua_Result != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT LUA_STR_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    byte luaStrLen = buff.ReadUInt8();
                    if (luaStrLen != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "Lua string: {0}", buff.ReadString(luaStrLen));
                    }

                    Log.outDebug(LogFilter.Warden, "RESULT LUA_STR_CHECK passed, CheckId {0} account Id {1}", id, _session.GetAccountId());
                    break;
                }

                case WardenCheckType.MPQ:
                {
                    byte Mpq_Result = buff.ReadUInt8();

                    if (Mpq_Result != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MPQ_CHECK not 0x00 account id {0}", _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    if (!buff.ReadBytes(20).Compare(rs.ToByteArray()))         // SHA1
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MPQ_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    Log.outDebug(LogFilter.Warden, "RESULT MPQ_CHECK passed, CheckId {0} account Id {1}", id, _session.GetAccountId());
                    break;
                }

                default:                                            // Should never happen
                    break;
                }
            }

            if (checkFailed > 0)
            {
                WardenCheck check = Global.WardenCheckMgr.GetWardenDataById(checkFailed);
                Log.outWarn(LogFilter.Warden, "{0} failed Warden check {1}. Action: {2}", _session.GetPlayerInfo(), checkFailed, Penalty(check));
            }

            // Set hold off timer, minimum timer should at least be 1 second
            uint holdOff = WorldConfig.GetUIntValue(WorldCfg.WardenClientCheckHoldoff);

            _checkTimer = (holdOff < 1 ? 1 : holdOff) * Time.InMilliseconds;
        }
Beispiel #8
0
        public void LoadDisables()
        {
            uint oldMSTime = Time.GetMSTime();

            // reload case
            m_DisableMap.Clear();

            SQLResult result = DB.World.Query("SELECT sourceType, entry, flags, params_0, params_1 FROM disables");

            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 disables. DB table `disables` is empty!");
                return;
            }

            uint total_count = 0;

            do
            {
                DisableType type = (DisableType)result.Read <uint>(0);
                if (type >= DisableType.Max)
                {
                    Log.outError(LogFilter.Sql, "Invalid type {0} specified in `disables` table, skipped.", type);
                    continue;
                }

                uint   entry    = result.Read <uint>(1);
                byte   flags    = result.Read <byte>(2);
                string params_0 = result.Read <string>(3);
                string params_1 = result.Read <string>(4);

                DisableData data = new DisableData();
                data.flags = flags;

                switch (type)
                {
                case DisableType.Spell:
                    if (!(Global.SpellMgr.HasSpellInfo(entry, Difficulty.None) || flags.HasAnyFlag <byte>(DisableFlags.SpellDeprecatedSpell)))
                    {
                        Log.outError(LogFilter.Sql, "Spell entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }

                    if (flags == 0 || flags > DisableFlags.MaxSpell)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags for spell {0} are invalid, skipped.", entry);
                        continue;
                    }

                    if (flags.HasAnyFlag(DisableFlags.SpellMap))
                    {
                        var array = new StringArray(params_0, ',');
                        for (byte i = 0; i < array.Length;)
                        {
                            if (uint.TryParse(array[i++], out uint id))
                            {
                                data.param0.Add(id);
                            }
                        }
                    }

                    if (flags.HasAnyFlag(DisableFlags.SpellArea))
                    {
                        var array = new StringArray(params_1, ',');
                        for (byte i = 0; i < array.Length;)
                        {
                            if (uint.TryParse(array[i++], out uint id))
                            {
                                data.param1.Add(id);
                            }
                        }
                    }

                    break;

                // checked later
                case DisableType.Quest:
                    break;

                case DisableType.Map:
                case DisableType.LFGMap:
                {
                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry);
                    if (mapEntry == null)
                    {
                        Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    bool isFlagInvalid = false;
                    switch (mapEntry.InstanceType)
                    {
                    case MapTypes.Common:
                        if (flags != 0)
                        {
                            isFlagInvalid = true;
                        }
                        break;

                    case MapTypes.Instance:
                    case MapTypes.Raid:
                        if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Heroic) == null)
                        {
                            flags -= DisableFlags.DungeonStatusHeroic;
                        }
                        if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic10Man) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Raid10HC) == null)
                        {
                            flags -= DisableFlags.DungeonStatusHeroic10Man;
                        }
                        if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic25Man) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Raid25HC) == null)
                        {
                            flags -= DisableFlags.DungeonStatusHeroic25Man;
                        }
                        if (flags == 0)
                        {
                            isFlagInvalid = true;
                        }
                        break;

                    case MapTypes.Battleground:
                    case MapTypes.Arena:
                        Log.outError(LogFilter.Sql, "Battlegroundmap {0} specified to be disabled in map case, skipped.", entry);
                        continue;
                    }
                    if (isFlagInvalid)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags for map {0} are invalid, skipped.", entry);
                        continue;
                    }
                    break;
                }

                case DisableType.Battleground:
                    if (!CliDB.BattlemasterListStorage.ContainsKey(entry))
                    {
                        Log.outError(LogFilter.Sql, "Battlegroundentry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    if (flags != 0)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags specified for Battleground{0}, useless data.", entry);
                    }
                    break;

                case DisableType.OutdoorPVP:
                    if (entry > (int)OutdoorPvPTypes.Max)
                    {
                        Log.outError(LogFilter.Sql, "OutdoorPvPTypes value {0} from `disables` is invalid, skipped.", entry);
                        continue;
                    }
                    if (flags != 0)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags specified for outdoor PvP {0}, useless data.", entry);
                    }
                    break;

                case DisableType.Criteria:
                    if (Global.CriteriaMgr.GetCriteria(entry) == null)
                    {
                        Log.outError(LogFilter.Sql, "Criteria entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    if (flags != 0)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags specified for Criteria {0}, useless data.", entry);
                    }
                    break;

                case DisableType.VMAP:
                {
                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry);
                    if (mapEntry == null)
                    {
                        Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    switch (mapEntry.InstanceType)
                    {
                    case MapTypes.Common:
                        if (flags.HasAnyFlag(DisableFlags.VmapAreaFlag))
                        {
                            Log.outInfo(LogFilter.Server, "Areaflag disabled for world map {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLiquidStatus))
                        {
                            Log.outInfo(LogFilter.Server, "Liquid status disabled for world map {0}.", entry);
                        }
                        break;

                    case MapTypes.Instance:
                    case MapTypes.Raid:
                        if (flags.HasAnyFlag(DisableFlags.VmapHeight))
                        {
                            Log.outInfo(LogFilter.Server, "Height disabled for instance map {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLOS))
                        {
                            Log.outInfo(LogFilter.Server, "LoS disabled for instance map {0}.", entry);
                        }
                        break;

                    case MapTypes.Battleground:
                        if (flags.HasAnyFlag(DisableFlags.VmapHeight))
                        {
                            Log.outInfo(LogFilter.Server, "Height disabled for Battlegroundmap {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLOS))
                        {
                            Log.outInfo(LogFilter.Server, "LoS disabled for Battlegroundmap {0}.", entry);
                        }
                        break;

                    case MapTypes.Arena:
                        if (flags.HasAnyFlag(DisableFlags.VmapHeight))
                        {
                            Log.outInfo(LogFilter.Server, "Height disabled for arena map {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLOS))
                        {
                            Log.outInfo(LogFilter.Server, "LoS disabled for arena map {0}.", entry);
                        }
                        break;

                    default:
                        break;
                    }
                    break;
                }

                case DisableType.MMAP:
                {
                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry);
                    if (mapEntry == null)
                    {
                        Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    switch (mapEntry.InstanceType)
                    {
                    case MapTypes.Common:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for world map {0}.", entry);
                        break;

                    case MapTypes.Instance:
                    case MapTypes.Raid:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for instance map {0}.", entry);
                        break;

                    case MapTypes.Battleground:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for Battlegroundmap {0}.", entry);
                        break;

                    case MapTypes.Arena:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for arena map {0}.", entry);
                        break;

                    default:
                        break;
                    }
                    break;
                }

                default:
                    break;
                }
                if (!m_DisableMap.ContainsKey(type))
                {
                    m_DisableMap[type] = new Dictionary <uint, DisableData>();
                }

                m_DisableMap[type].Add(entry, data);
                ++total_count;
            }while (result.NextRow());

            Log.outInfo(LogFilter.ServerLoading, "Loaded {0} disables in {1} ms", total_count, Time.GetMSTimeDiffToNow(oldMSTime));
        }
Beispiel #9
0
        public override void RequestData()
        {
            Log.outDebug(LogFilter.Warden, "Request data");

            // If all checks were done, fill the todo list again
            if (_memChecksTodo.Empty())
            {
                _memChecksTodo.AddRange(Global.WardenCheckMgr.MemChecksIdPool);
            }

            if (_otherChecksTodo.Empty())
            {
                _otherChecksTodo.AddRange(Global.WardenCheckMgr.OtherChecksIdPool);
            }

            _serverTicks = Time.GetMSTime();

            ushort          id;
            WardenCheckType type;
            WardenCheck     wd;

            _currentChecks.Clear();

            // Build check request
            for (uint i = 0; i < WorldConfig.GetUIntValue(WorldCfg.WardenNumMemChecks); ++i)
            {
                // If todo list is done break loop (will be filled on next Update() run)
                if (_memChecksTodo.Empty())
                {
                    break;
                }

                // Get check id from the end and remove it from todo
                id = _memChecksTodo.Last();
                _memChecksTodo.Remove(id);

                // Add the id to the list sent in this cycle
                _currentChecks.Add(id);
            }

            ByteBuffer buffer = new ByteBuffer();

            buffer.WriteUInt8(WardenOpcodes.Smsg_CheatChecksRequest);

            for (uint i = 0; i < WorldConfig.GetUIntValue(WorldCfg.WardenNumOtherChecks); ++i)
            {
                // If todo list is done break loop (will be filled on next Update() run)
                if (_otherChecksTodo.Empty())
                {
                    break;
                }

                // Get check id from the end and remove it from todo
                id = _otherChecksTodo.Last();
                _otherChecksTodo.Remove(id);

                // Add the id to the list sent in this cycle
                _currentChecks.Add(id);

                wd = Global.WardenCheckMgr.GetWardenDataById(id);

                switch (wd.Type)
                {
                case WardenCheckType.MPQ:
                case WardenCheckType.LuaStr:
                case WardenCheckType.Driver:
                    buffer.WriteUInt8(wd.Str.GetByteCount());
                    buffer.WriteString(wd.Str);
                    break;

                default:
                    break;
                }
            }

            byte xorByte = _inputKey[0];

            // Add TIMING_CHECK
            buffer.WriteUInt8(0x00);
            buffer.WriteUInt8((int)WardenCheckType.Timing ^ xorByte);

            byte index = 1;

            foreach (var checkId in _currentChecks)
            {
                wd = Global.WardenCheckMgr.GetWardenDataById(checkId);

                type = wd.Type;
                buffer.WriteUInt8((int)type ^ xorByte);
                switch (type)
                {
                case WardenCheckType.Memory:
                {
                    buffer.WriteUInt8(0x00);
                    buffer.WriteUInt32(wd.Address);
                    buffer.WriteUInt8(wd.Length);
                    break;
                }

                case WardenCheckType.PageA:
                case WardenCheckType.PageB:
                {
                    buffer.WriteBytes(wd.Data.ToByteArray());
                    buffer.WriteUInt32(wd.Address);
                    buffer.WriteUInt8(wd.Length);
                    break;
                }

                case WardenCheckType.MPQ:
                case WardenCheckType.LuaStr:
                {
                    buffer.WriteUInt8(index++);
                    break;
                }

                case WardenCheckType.Driver:
                {
                    buffer.WriteBytes(wd.Data.ToByteArray());
                    buffer.WriteUInt8(index++);
                    break;
                }

                case WardenCheckType.Module:
                {
                    uint seed = RandomHelper.Rand32();
                    buffer.WriteUInt32(seed);
                    HmacHash hmac = new HmacHash(BitConverter.GetBytes(seed));
                    hmac.Finish(wd.Str);
                    buffer.WriteBytes(hmac.Digest);
                    break;
                }

                /*case PROC_CHECK:
                 * {
                 *  buff.append(wd.i.AsByteArray(0, false).get(), wd.i.GetNumBytes());
                 *  buff << uint8(index++);
                 *  buff << uint8(index++);
                 *  buff << uint32(wd.Address);
                 *  buff << uint8(wd.Length);
                 *  break;
                 * }*/
                default:
                    break;                                          // Should never happen
                }
            }
            buffer.WriteUInt8(xorByte);

            WardenDataServer packet = new WardenDataServer();

            packet.Data = EncryptData(buffer.GetData());
            _session.SendPacket(packet);

            _dataSent = true;

            string stream = "Sent check id's: ";

            foreach (var checkId in _currentChecks)
            {
                stream += checkId + " ";
            }

            Log.outDebug(LogFilter.Warden, stream);
        }
Beispiel #10
0
        void HandleMovementOpcode(ClientOpcodes opcode, MovementInfo movementInfo)
        {
            Unit   mover    = GetPlayer().m_unitMovedByMe;
            Player plrMover = mover.ToPlayer();

            if (plrMover && plrMover.IsBeingTeleported())
            {
                return;
            }

            GetPlayer().ValidateMovementInfo(movementInfo);

            if (movementInfo.Guid != mover.GetGUID())
            {
                Log.outError(LogFilter.Network, "HandleMovementOpcodes: guid error");
                return;
            }
            if (!movementInfo.Pos.IsPositionValid())
            {
                Log.outError(LogFilter.Network, "HandleMovementOpcodes: Invalid Position");
                return;
            }

            // stop some emotes at player move
            if (plrMover && (plrMover.GetUInt32Value(UnitFields.NpcEmotestate) != 0))
            {
                plrMover.SetUInt32Value(UnitFields.NpcEmotestate, (uint)Emote.OneshotNone);
            }

            //handle special cases
            if (!movementInfo.transport.guid.IsEmpty())
            {
                if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50)
                {
                    return;
                }

                if (!GridDefines.IsValidMapCoord(movementInfo.Pos.posX + movementInfo.transport.pos.posX, movementInfo.Pos.posY + movementInfo.transport.pos.posY,
                                                 movementInfo.Pos.posZ + movementInfo.transport.pos.posZ, movementInfo.Pos.Orientation + movementInfo.transport.pos.Orientation))
                {
                    return;
                }

                if (plrMover)
                {
                    if (!plrMover.GetTransport())
                    {
                        Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid);
                        if (transport)
                        {
                            transport.AddPassenger(plrMover);
                        }
                    }
                    else if (plrMover.GetTransport().GetGUID() != movementInfo.transport.guid)
                    {
                        plrMover.GetTransport().RemovePassenger(plrMover);
                        Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid);
                        if (transport)
                        {
                            transport.AddPassenger(plrMover);
                        }
                        else
                        {
                            movementInfo.ResetTransport();
                        }
                    }
                }

                if (!mover.GetTransport() && !mover.GetVehicle())
                {
                    GameObject go = mover.GetMap().GetGameObject(movementInfo.transport.guid);
                    if (!go || go.GetGoType() != GameObjectTypes.Transport)
                    {
                        movementInfo.transport.Reset();
                    }
                }
            }
            else if (plrMover && plrMover.GetTransport())                // if we were on a transport, leave
            {
                plrMover.GetTransport().RemovePassenger(plrMover);
            }

            // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
            if (opcode == ClientOpcodes.MoveFallLand && plrMover && !plrMover.IsInFlight())
            {
                plrMover.HandleFall(movementInfo);
            }

            if (plrMover && movementInfo.HasMovementFlag(MovementFlag.Swimming) != plrMover.IsInWater())
            {
                // now client not include swimming flag in case jumping under water
                plrMover.SetInWater(!plrMover.IsInWater() || plrMover.GetMap().IsUnderWater(plrMover.GetPhaseShift(), movementInfo.Pos.posX, movementInfo.Pos.posY, movementInfo.Pos.posZ));
            }

            uint mstime = Time.GetMSTime();

            if (m_clientTimeDelay == 0)
            {
                m_clientTimeDelay = mstime - movementInfo.Time;
            }

            movementInfo.Time = movementInfo.Time + m_clientTimeDelay;

            movementInfo.Guid    = mover.GetGUID();
            mover.m_movementInfo = movementInfo;

            // Some vehicles allow the passenger to turn by himself
            Vehicle vehicle = mover.GetVehicle();

            if (vehicle)
            {
                VehicleSeatRecord seat = vehicle.GetSeatForPassenger(mover);
                if (seat != null)
                {
                    if (seat.Flags.HasAnyFlag(VehicleSeatFlags.AllowTurning))
                    {
                        if (movementInfo.Pos.GetOrientation() != mover.GetOrientation())
                        {
                            mover.SetOrientation(movementInfo.Pos.GetOrientation());
                            mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Turning);
                        }
                    }
                }
                return;
            }

            mover.UpdatePosition(movementInfo.Pos);

            MoveUpdate moveUpdate = new MoveUpdate();

            moveUpdate.Status = mover.m_movementInfo;
            mover.SendMessageToSet(moveUpdate, GetPlayer());

            if (plrMover)                                            // nothing is charmed, or player charmed
            {
                if (plrMover.IsSitState() && movementInfo.HasMovementFlag(MovementFlag.MaskMoving | MovementFlag.MaskTurning))
                {
                    plrMover.SetStandState(UnitStandStateType.Stand);
                }

                plrMover.UpdateFallInformationIfNeed(movementInfo, opcode);

                if (movementInfo.Pos.posZ < plrMover.GetMap().GetMinHeight(movementInfo.Pos.GetPositionX(), movementInfo.Pos.GetPositionY()))
                {
                    if (!(plrMover.GetBattleground() && plrMover.GetBattleground().HandlePlayerUnderMap(GetPlayer())))
                    {
                        // NOTE: this is actually called many times while falling
                        // even after the player has been teleported away
                        // @todo discard movement packets after the player is rooted
                        if (plrMover.IsAlive())
                        {
                            plrMover.SetFlag(PlayerFields.Flags, PlayerFlags.IsOutOfBounds);
                            plrMover.EnvironmentalDamage(EnviromentalDamage.FallToVoid, (uint)GetPlayer().GetMaxHealth());
                            // player can be alive if GM/etc
                            // change the death state to CORPSE to prevent the death timer from
                            // starting in the next player update
                            if (plrMover.IsAlive())
                            {
                                plrMover.KillPlayer();
                            }
                        }
                    }
                }
                else
                {
                    plrMover.RemoveFlag(PlayerFields.Flags, PlayerFlags.IsOutOfBounds);
                }

                if (opcode == ClientOpcodes.MoveJump)
                {
                    plrMover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Jump, 605); // Mind Control
                    plrMover.ProcSkillsAndAuras(null, ProcFlags.Jump, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
                }
            }
        }
Beispiel #11
0
        public void LoadFromDB()
        {
            uint oldMSTime = Time.GetMSTime();

            uint count = 0;

            _maxEventId  = 0;
            _maxInviteId = 0;

            //                                              0        1      2      3            4          5          6     7      8
            SQLResult result = DB.Characters.Query("SELECT EventID, Owner, Title, Description, EventType, TextureID, Date, Flags, LockDate FROM calendar_events");

            if (!result.IsEmpty())
            {
                do
                {
                    ulong             eventID     = result.Read <ulong>(0);
                    ObjectGuid        ownerGUID   = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(1));
                    string            title       = result.Read <string>(2);
                    string            description = result.Read <string>(3);
                    CalendarEventType type        = (CalendarEventType)result.Read <byte>(4);
                    int           textureID       = result.Read <int>(5);
                    long          date            = result.Read <long>(6);
                    CalendarFlags flags           = (CalendarFlags)result.Read <uint>(7);
                    long          lockDate        = result.Read <long>(8);
                    ulong         guildID         = 0;

                    if (flags.HasAnyFlag(CalendarFlags.GuildEvent) || flags.HasAnyFlag(CalendarFlags.WithoutInvites))
                    {
                        guildID = Global.CharacterCacheStorage.GetCharacterGuildIdByGuid(ownerGUID);
                    }

                    CalendarEvent calendarEvent = new(eventID, ownerGUID, guildID, type, textureID, date, flags, title, description, lockDate);
                    _events.Add(calendarEvent);

                    _maxEventId = Math.Max(_maxEventId, eventID);

                    ++count;
                }while (result.NextRow());
            }

            Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} calendar events in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
            count     = 0;
            oldMSTime = Time.GetMSTime();

            //                                    0         1        2        3       4       5             6               7
            result = DB.Characters.Query("SELECT InviteID, EventID, Invitee, Sender, Status, ResponseTime, ModerationRank, Note FROM calendar_invites");
            if (!result.IsEmpty())
            {
                do
                {
                    ulong                inviteId   = result.Read <ulong>(0);
                    ulong                eventId    = result.Read <ulong>(1);
                    ObjectGuid           invitee    = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(2));
                    ObjectGuid           senderGUID = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(3));
                    CalendarInviteStatus status     = (CalendarInviteStatus)result.Read <byte>(4);
                    long responseTime           = result.Read <long>(5);
                    CalendarModerationRank rank = (CalendarModerationRank)result.Read <byte>(6);
                    string note = result.Read <string>(7);

                    CalendarInvite invite = new(inviteId, eventId, invitee, senderGUID, responseTime, status, rank, note);
                    _invites.Add(eventId, invite);

                    _maxInviteId = Math.Max(_maxInviteId, inviteId);

                    ++count;
                }while (result.NextRow());
            }

            Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} calendar invites in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");

            for (ulong i = 1; i < _maxEventId; ++i)
            {
                if (GetEvent(i) == null)
                {
                    _freeEventIds.Add(i);
                }
            }

            for (ulong i = 1; i < _maxInviteId; ++i)
            {
                if (GetInvite(i) == null)
                {
                    _freeInviteIds.Add(i);
                }
            }
        }
Beispiel #12
0
        public void LoadFromDB()
        {
            // Pool templates
            {
                uint oldMSTime = Time.GetMSTime();

                SQLResult result = DB.World.Query("SELECT entry, max_limit FROM pool_template");
                if (result.IsEmpty())
                {
                    mPoolTemplate.Clear();
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 object pools. DB table `pool_template` is empty.");
                    return;
                }

                uint count = 0;
                do
                {
                    uint pool_id = result.Read <uint>(0);

                    PoolTemplateData pPoolTemplate = new();
                    pPoolTemplate.MaxLimit = result.Read <uint>(1);
                    mPoolTemplate[pool_id] = pPoolTemplate;
                    ++count;
                }while (result.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} objects pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
            }

            // Creatures

            Log.outInfo(LogFilter.ServerLoading, "Loading Creatures Pooling Data...");
            {
                uint oldMSTime = Time.GetMSTime();

                //                                         1        2            3
                SQLResult result = DB.World.Query("SELECT spawnId, poolSpawnId, chance FROM pool_members WHERE type = 0");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 creatures in  pools. DB table `pool_creature` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        ulong guid    = result.Read <ulong>(0);
                        uint  pool_id = result.Read <uint>(1);
                        float chance  = result.Read <float>(2);

                        CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
                        if (data == null)
                        {
                            Log.outError(LogFilter.Sql, "`pool_creature` has a non existing creature spawn (GUID: {0}) defined for pool id ({1}), skipped.", guid, pool_id);
                            continue;
                        }
                        if (!mPoolTemplate.ContainsKey(pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_creature` pool id ({0}) is not in `pool_template`, skipped.", pool_id);
                            continue;
                        }
                        if (chance < 0 || chance > 100)
                        {
                            Log.outError(LogFilter.Sql, "`pool_creature` has an invalid chance ({0}) for creature guid ({1}) in pool id ({2}), skipped.", chance, guid, pool_id);
                            continue;
                        }
                        PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id];
                        PoolObject       plObject      = new(guid, chance);

                        if (!mPoolCreatureGroups.ContainsKey(pool_id))
                        {
                            mPoolCreatureGroups[pool_id] = new PoolGroup <Creature>();
                        }

                        PoolGroup <Creature> cregroup = mPoolCreatureGroups[pool_id];
                        cregroup.SetPoolId(pool_id);
                        cregroup.AddEntry(plObject, pPoolTemplate.MaxLimit);

                        mCreatureSearchMap.Add(guid, pool_id);
                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creatures in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // Gameobjects

            Log.outInfo(LogFilter.ServerLoading, "Loading Gameobject Pooling Data...");
            {
                uint oldMSTime = Time.GetMSTime();

                //                                         1        2            3
                SQLResult result = DB.World.Query("SELECT spawnId, poolSpawnId, chance FROM pool_members WHERE type = 1");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 gameobjects in  pools. DB table `pool_gameobject` is empty.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        ulong guid    = result.Read <ulong>(0);
                        uint  pool_id = result.Read <uint>(1);
                        float chance  = result.Read <float>(2);

                        GameObjectData data = Global.ObjectMgr.GetGameObjectData(guid);
                        if (data == null)
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` has a non existing gameobject spawn (GUID: {0}) defined for pool id ({1}), skipped.", guid, pool_id);
                            continue;
                        }

                        GameObjectTemplate goinfo = Global.ObjectMgr.GetGameObjectTemplate(data.Id);
                        if (goinfo.type != GameObjectTypes.Chest &&
                            goinfo.type != GameObjectTypes.FishingHole &&
                            goinfo.type != GameObjectTypes.GatheringNode &&
                            goinfo.type != GameObjectTypes.Goober)
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` has a not lootable gameobject spawn (GUID: {0}, type: {1}) defined for pool id ({2}), skipped.", guid, goinfo.type, pool_id);
                            continue;
                        }

                        if (!mPoolTemplate.ContainsKey(pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` pool id ({0}) is not in `pool_template`, skipped.", pool_id);
                            continue;
                        }

                        if (chance < 0 || chance > 100)
                        {
                            Log.outError(LogFilter.Sql, "`pool_gameobject` has an invalid chance ({0}) for gameobject guid ({1}) in pool id ({2}), skipped.", chance, guid, pool_id);
                            continue;
                        }

                        PoolTemplateData pPoolTemplate = mPoolTemplate[pool_id];
                        PoolObject       plObject      = new(guid, chance);

                        if (!mPoolGameobjectGroups.ContainsKey(pool_id))
                        {
                            mPoolGameobjectGroups[pool_id] = new PoolGroup <GameObject>();
                        }

                        PoolGroup <GameObject> gogroup = mPoolGameobjectGroups[pool_id];
                        gogroup.SetPoolId(pool_id);
                        gogroup.AddEntry(plObject, pPoolTemplate.MaxLimit);

                        mGameobjectSearchMap.Add(guid, pool_id);
                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} gameobject in pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // Pool of pools

            Log.outInfo(LogFilter.ServerLoading, "Loading Mother Pooling Data...");
            {
                uint oldMSTime = Time.GetMSTime();

                //                                         1        2            3
                SQLResult result = DB.World.Query("SELECT spawnId, poolSpawnId, chance FROM pool_members WHERE type = 2");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 pools in pools");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint  child_pool_id  = result.Read <uint>(0);
                        uint  mother_pool_id = result.Read <uint>(1);
                        float chance         = result.Read <float>(2);

                        if (!mPoolTemplate.ContainsKey(mother_pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` mother_pool id ({0}) is not in `pool_template`, skipped.", mother_pool_id);
                            continue;
                        }
                        if (!mPoolTemplate.ContainsKey(child_pool_id))
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` included pool_id ({0}) is not in `pool_template`, skipped.", child_pool_id);
                            continue;
                        }
                        if (mother_pool_id == child_pool_id)
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` pool_id ({0}) includes itself, dead-lock detected, skipped.", child_pool_id);
                            continue;
                        }
                        if (chance < 0 || chance > 100)
                        {
                            Log.outError(LogFilter.Sql, "`pool_pool` has an invalid chance ({0}) for pool id ({1}) in mother pool id ({2}), skipped.", chance, child_pool_id, mother_pool_id);
                            continue;
                        }
                        PoolTemplateData pPoolTemplateMother = mPoolTemplate[mother_pool_id];
                        PoolObject       plObject            = new(child_pool_id, chance);

                        if (!mPoolPoolGroups.ContainsKey(mother_pool_id))
                        {
                            mPoolPoolGroups[mother_pool_id] = new PoolGroup <Pool>();
                        }

                        PoolGroup <Pool> plgroup = mPoolPoolGroups[mother_pool_id];
                        plgroup.SetPoolId(mother_pool_id);
                        plgroup.AddEntry(plObject, pPoolTemplateMother.MaxLimit);

                        mPoolSearchMap.Add(child_pool_id, mother_pool_id);
                        ++count;
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Loaded {0} pools in mother pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }

            // The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks
            Log.outInfo(LogFilter.ServerLoading, "Starting objects pooling system...");
            {
                uint oldMSTime = Time.GetMSTime();

                SQLResult result = DB.World.Query("SELECT DISTINCT pool_template.entry, pool_members.spawnId, pool_members.poolSpawnId FROM pool_template" +
                                                  " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry" +
                                                  " LEFT JOIN pool_members ON pool_members.type = 2 AND pool_template.entry = pool_members.spawnId WHERE game_event_pool.pool_entry IS NULL");

                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Pool handling system initialized, 0 pools spawned.");
                }
                else
                {
                    uint count = 0;
                    do
                    {
                        uint pool_entry   = result.Read <uint>(0);
                        uint pool_pool_id = result.Read <uint>(1);

                        if (!CheckPool(pool_entry))
                        {
                            if (pool_pool_id != 0)
                            {
                                // The pool is a child pool in pool_pool table. Ideally we should remove it from the pool handler to ensure it never gets spawned,
                                // however that could recursively invalidate entire chain of mother pools. It can be done in the future but for now we'll do nothing.
                                Log.outError(LogFilter.Sql, "Pool Id {0} has no equal chance pooled entites defined and explicit chance sum is not 100. This broken pool is a child pool of Id {1} and cannot be safely removed.", pool_entry, result.Read <uint>(2));
                            }
                            else
                            {
                                Log.outError(LogFilter.Sql, "Pool Id {0} has no equal chance pooled entites defined and explicit chance sum is not 100. The pool will not be spawned.", pool_entry);
                            }
                            continue;
                        }

                        // Don't spawn child pools, they are spawned recursively by their parent pools
                        if (pool_pool_id == 0)
                        {
                            SpawnPool(pool_entry);
                            count++;
                        }
                    }while (result.NextRow());

                    Log.outInfo(LogFilter.ServerLoading, "Pool handling system initialized, {0} pools spawned in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
                }
            }
        }
Beispiel #13
0
 public void RecordUpdateTimeReset()
 {
     _recordedTime = Time.GetMSTime();
 }