static bool HandleBanListHelper(PreparedQueryResult result, ChatHandler* handler) { handler->PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT); // Chat short output if (handler->GetSession()) { do { Field* fields = result->Fetch(); uint32 accountid = fields[0].GetUInt32(); QueryResult banResult = LoginDatabase.PQuery("SELECT account.username FROM account, account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id", accountid); if (banResult) { Field* fields2 = banResult->Fetch(); handler->PSendSysMessage("%s", fields2[0].GetCString()); } } while (result->NextRow()); } // Console wide output else { handler->SendSysMessage(LANG_BANLIST_ACCOUNTS); handler->SendSysMessage(" ==============================================================================="); handler->SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER); do { handler->SendSysMessage("-------------------------------------------------------------------------------"); Field* fields = result->Fetch(); uint32 accountId = fields[0].GetUInt32(); std::string accountName; // "account" case, name can be get in same query if (result->GetFieldCount() > 1) accountName = fields[1].GetString(); // "character" case, name need extract from another DB else AccountMgr::GetName(accountId, accountName); // No SQL injection. id is uint32. QueryResult banInfo = LoginDatabase.PQuery("SELECT bandate, unbandate, bannedby, banreason FROM account_banned WHERE id = %u ORDER BY unbandate", accountId); if (banInfo) { Field* fields2 = banInfo->Fetch(); do { time_t timeBan = time_t(fields2[0].GetUInt32()); tm* tmBan = localtime(&timeBan); if (fields2[0].GetUInt32() == fields2[1].GetUInt32()) { handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", accountName.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, fields2[2].GetCString(), fields2[3].GetCString()); } else { time_t timeUnban = time_t(fields2[1].GetUInt32()); tm* tmUnban = localtime(&timeUnban); handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", accountName.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min, fields2[2].GetCString(), fields2[3].GetCString()); } } while (banInfo->NextRow()); } } while (result->NextRow()); handler->SendSysMessage(" ==============================================================================="); } return true; }
void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime) { // global reset for all instances of the given map MapEntry const *mapEntry = sMapStore.LookupEntry(mapid); if (!mapEntry->Instanceable()) return; time_t now = time(NULL); if (!warn) { MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty); if (!mapDiff || !mapDiff->resetTime) { sLog->outError("InstanceSaveManager::ResetOrWarnAll: not valid difficulty or no reset delay for map %d", mapid); return; } // remove all binds to instances of the given map for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end();) { if (itr->second->GetMapId() == mapid && itr->second->GetDifficulty() == difficulty) _ResetSave(itr); else ++itr; } // delete them from the DB, even if not loaded SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty); trans->PAppend("DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty); trans->PAppend("DELETE FROM instance WHERE map = '%u' and difficulty='%u'", mapid, difficulty); CharacterDatabase.CommitTransaction(trans); // calculate the next reset time uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME))/DAY) * DAY); if (period < DAY) period = DAY; uint64 next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff; SetResetTimeFor(mapid, difficulty, next_reset); ScheduleReset(true, time_t(next_reset-3600), InstResetEvent(1, mapid, difficulty, 0)); // update it in the DB CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%d' AND difficulty = '%d'", uint32(next_reset), mapid, difficulty); } // note: this isn't fast but it's meant to be executed very rarely Map const *map = sMapMgr->CreateBaseMap(mapid); // _not_ include difficulty MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps(); MapInstanced::InstancedMaps::iterator mitr; uint32 timeLeft; for (mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr) { Map *map2 = mitr->second; if (!map2->IsDungeon()) continue; if (warn) { if (now <= resetTime) timeLeft = 0; else timeLeft = uint32(now - resetTime); ((InstanceMap*)map2)->SendResetWarnings(timeLeft); } else ((InstanceMap*)map2)->Reset(INSTANCE_RESET_GLOBAL); } // TODO: delete creature/gameobject respawn times even if the maps are not loaded }
void Date::setTimeFromAppleEpoch(double appleTime) { _time = time_t(978307200 + appleTime); }
void InstanceScenario::LoadInstanceData(uint32 instanceId) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SCENARIO_INSTANCE_CRITERIA_FOR_INSTANCE); stmt->setUInt32(0, instanceId); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); time_t now = time(nullptr); std::vector<CriteriaTree const*> criteriaTrees; do { Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); uint64 counter = fields[1].GetUInt64(); time_t date = time_t(fields[2].GetUInt32()); Criteria const* criteria = sCriteriaMgr->GetCriteria(id); if (!criteria) { // Removing non-existing criteria data for all instances TC_LOG_ERROR("criteria.instancescenarios", "Removing scenario criteria %u data from the table `instance_scenario_progress`.", id); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_SCENARIO_INSTANCE_CRITERIA); stmt->setUInt32(0, instanceId); stmt->setUInt32(1, uint32(id)); trans->Append(stmt); continue; } if (criteria->Entry->StartTimer && time_t(date + criteria->Entry->StartTimer) < now) continue; switch (CriteriaTypes(criteria->Entry->Type)) { // Blizzard appears to only stores creatures killed progress for unknown reasons. Either technical shortcoming or intentional case CRITERIA_TYPE_KILL_CREATURE: break; default: continue; } SetCriteriaProgress(criteria, counter, nullptr, PROGRESS_SET); if (CriteriaTreeList const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(criteria->ID)) for (CriteriaTree const* tree : *trees) criteriaTrees.push_back(tree); } while (result->NextRow()); CharacterDatabase.CommitTransaction(trans); for (CriteriaTree const* tree : criteriaTrees) { ScenarioStepEntry const* step = tree->ScenarioStep; if (!step) continue; if (IsCompletedCriteriaTree(tree)) SetStepState(step, SCENARIO_STEP_DONE); } } }
void GameEventMgr::LoadFromDB() { { QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM game_event"); if( !result ) { sLog.outString(">> Table game_event is empty."); sLog.outString(); return; } Field *fields = result->Fetch(); uint32 max_event_id = fields[0].GetUInt16(); delete result; mGameEvent.resize(max_event_id+1); } QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,description FROM game_event"); if (!result) { mGameEvent.clear(); sLog.outString(">> Table game_event is empty!"); sLog.outString(); return; } uint32 count = 0; { BarGoLink bar(result->GetRowCount()); do { ++count; Field *fields = result->Fetch(); bar.step(); uint16 event_id = fields[0].GetUInt16(); if (event_id == 0) { sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id); continue; } GameEventData& pGameEvent = mGameEvent[event_id]; uint64 starttime = fields[1].GetUInt64(); pGameEvent.start = time_t(starttime); uint64 endtime = fields[2].GetUInt64(); pGameEvent.end = time_t(endtime); pGameEvent.occurence = fields[3].GetUInt32(); pGameEvent.length = fields[4].GetUInt32(); pGameEvent.holiday_id = HolidayIds(fields[5].GetUInt32()); if(pGameEvent.length==0) // length>0 is validity check { sLog.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id); continue; } pGameEvent.description = fields[6].GetCppString(); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u game events", count ); } std::map<uint16,int16> pool2event; // for check unique spawn event associated with pool std::map<uint32,int16> creature2event; // for check unique spawn event associated with creature std::map<uint32,int16> go2event; // for check unique spawn event associated with gameobject // list only positive event top pools, filled at creature/gameobject loading mGameEventSpawnPoolIds.resize(mGameEvent.size()); mGameEventCreatureGuids.resize(mGameEvent.size()*2-1); // 1 2 result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event " "FROM creature JOIN game_event_creature ON creature.guid = game_event_creature.guid"); count = 0; if (!result) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u creatures in game events", count ); } else { BarGoLink bar(result->GetRowCount()); do { Field *fields = result->Fetch(); bar.step(); uint32 guid = fields[0].GetUInt32(); int16 event_id = fields[1].GetInt16(); if (event_id == 0) { sLog.outErrorDb("`game_event_creature` game event id (%i) not allowed", event_id); continue; } if (!IsValidEvent(std::abs(event_id))) { sLog.outErrorDb("`game_event_creature` game event id (%i) not exist in `game_event`", event_id); continue; } int32 internal_event_id = mGameEvent.size() + event_id - 1; ++count; // spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case if (event_id > 0) { creature2event[guid] = event_id; // not list explicitly creatures from pools in event creature list if (uint16 topPoolId = sPoolMgr.IsPartOfTopPool<Creature>(guid)) { int16& eventRef = pool2event[topPoolId]; if (eventRef != 0) { if (eventRef != event_id) sLog.outErrorDb("`game_event_creature` have creature (GUID: %u) for event %i from pool or subpool of pool (ID: %u) but pool have already content from event %i. Pool don't must have content for different events!", guid, event_id, topPoolId, eventRef); } else { eventRef = event_id; mGameEventSpawnPoolIds[event_id].push_back(topPoolId); sPoolMgr.RemoveAutoSpawnForPool(topPoolId); } continue; } } GuidList& crelist = mGameEventCreatureGuids[internal_event_id]; crelist.push_back(guid); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u creatures in game events", count ); } mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1); // 1 2 result = WorldDatabase.Query("SELECT gameobject.guid, game_event_gameobject.event " "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid"); count = 0; if (!result) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u gameobjects in game events", count ); } else { BarGoLink bar(result->GetRowCount()); do { Field *fields = result->Fetch(); bar.step(); uint32 guid = fields[0].GetUInt32(); int16 event_id = fields[1].GetInt16(); if (event_id == 0) { sLog.outErrorDb("`game_event_gameobject` game event id (%i) not allowed", event_id); continue; } if (!IsValidEvent(std::abs(event_id))) { sLog.outErrorDb("`game_event_gameobject` game event id (%i) not exist in `game_event`", event_id); continue; } int32 internal_event_id = mGameEvent.size() + event_id - 1; ++count; // spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case if (event_id > 0) { go2event[guid] = event_id; // not list explicitly gameobjects from pools in event gameobject list if (uint16 topPoolId = sPoolMgr.IsPartOfTopPool<GameObject>(guid)) { int16& eventRef = pool2event[topPoolId]; if (eventRef != 0) { if (eventRef != event_id) sLog.outErrorDb("`game_event_gameobject` have gameobject (GUID: %u) for event %i from pool or subpool of pool (ID: %u) but pool have already content from event %i. Pool don't must have content for different events!", guid, event_id, topPoolId, eventRef); } else { eventRef = event_id; mGameEventSpawnPoolIds[event_id].push_back(topPoolId); sPoolMgr.RemoveAutoSpawnForPool(topPoolId); } continue; } } GuidList& golist = mGameEventGameobjectGuids[internal_event_id]; golist.push_back(guid); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u gameobjects in game events", count ); } // now recheck that all eventPools linked with events after our skip pools with parents for(std::map<uint16,int16>::const_iterator itr = pool2event.begin(); itr != pool2event.end(); ++itr) { uint16 pool_id = itr->first; int16 event_id = itr->second; sPoolMgr.CheckEventLinkAndReport(pool_id, event_id, creature2event, go2event); } mGameEventCreatureData.resize(mGameEvent.size()); // 0 1 2 result = WorldDatabase.Query("SELECT creature.guid, game_event_creature_data.event, game_event_creature_data.modelid," // 3 4 "game_event_creature_data.equipment_id, game_event_creature_data.entry_id, " // 5 6 "game_event_creature_data.spell_start, game_event_creature_data.spell_end " "FROM creature JOIN game_event_creature_data ON creature.guid=game_event_creature_data.guid"); count = 0; if (!result) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u creature reactions at game events", count ); } else { BarGoLink bar(result->GetRowCount()); do { Field *fields = result->Fetch(); bar.step(); uint32 guid = fields[0].GetUInt32(); uint16 event_id = fields[1].GetUInt16(); if (event_id == 0) { sLog.outErrorDb("`game_event_creature_data` game event id (%i) is reserved and can't be used." ,event_id); continue; } if (!IsValidEvent(event_id)) { sLog.outErrorDb("`game_event_creature_data` game event id (%u) not exist in `game_event`", event_id); continue; } ++count; GameEventCreatureDataList& equiplist = mGameEventCreatureData[event_id]; GameEventCreatureData newData; newData.modelid = fields[2].GetUInt32(); newData.equipment_id = fields[3].GetUInt32(); newData.entry_id = fields[4].GetUInt32(); newData.spell_id_start = fields[5].GetUInt32(); newData.spell_id_end = fields[6].GetUInt32(); if (newData.equipment_id && !sObjectMgr.GetEquipmentInfo(newData.equipment_id) && !sObjectMgr.GetEquipmentInfoRaw(newData.equipment_id)) { sLog.outErrorDb("Table `game_event_creature_data` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template` or `creature_equip_template_raw`, set to no equipment.", guid, newData.equipment_id); newData.equipment_id = 0; } if (newData.entry_id && !ObjectMgr::GetCreatureTemplate(newData.entry_id)) { sLog.outErrorDb("Table `game_event_creature_data` have creature (Guid: %u) with event time entry %u not found in table `creature_template`, set to no 0.", guid, newData.entry_id); newData.entry_id = 0; } if (newData.spell_id_start && !sSpellStore.LookupEntry(newData.spell_id_start)) { sLog.outErrorDb("Table `game_event_creature_data` have creature (Guid: %u) with nonexistent spell_start %u, set to no start spell.", guid, newData.spell_id_start); newData.spell_id_start = 0; } if (newData.spell_id_end && !sSpellStore.LookupEntry(newData.spell_id_end)) { sLog.outErrorDb("Table `game_event_creature_data` have creature (Guid: %u) with nonexistent spell_end %u, set to no end spell.", guid, newData.spell_id_end); newData.spell_id_end = 0; } equiplist.push_back(GameEventCreatureDataPair(guid, newData)); mGameEventCreatureDataPerGuid.insert(GameEventCreatureDataPerGuidMap::value_type(guid, event_id)); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString(">> Loaded %u creature reactions at game events", count ); } mGameEventQuests.resize(mGameEvent.size()); result = WorldDatabase.Query("SELECT quest, event FROM game_event_quest"); count = 0; if (!result) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u quests additions in game events", count ); } else { BarGoLink bar(result->GetRowCount()); do { Field *fields = result->Fetch(); bar.step(); uint32 quest = fields[0].GetUInt32(); uint16 event_id = fields[1].GetUInt16(); if (event_id == 0) { sLog.outErrorDb("`game_event_quest` game event id (%i) is reserved and can't be used.", event_id); continue; } if (!IsValidEvent(event_id)) { sLog.outErrorDb("`game_event_quest` game event id (%u) not exist in `game_event`", event_id); continue; } const Quest* pQuest = sObjectMgr.GetQuestTemplate(quest); if (!pQuest) { sLog.outErrorDb("Table `game_event_quest` contain entry for quest %u (event %u) but this quest does not exist. Skipping.", quest, event_id); continue; } // disable any event specific quest (for cases where creature is spawned, but event not active). const_cast<Quest*>(pQuest)->SetQuestActiveState(false); ++count; QuestList& questlist = mGameEventQuests[event_id]; questlist.push_back(quest); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u quest additions in game events", count ); } mGameEventMails.resize(mGameEvent.size()*2-1); result = WorldDatabase.Query("SELECT event, raceMask, quest, mailTemplateId, senderEntry FROM game_event_mail"); count = 0; if (!result) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u start/end game event mails", count ); } else { BarGoLink bar(result->GetRowCount()); do { Field *fields = result->Fetch(); bar.step(); uint16 event_id = fields[0].GetUInt16(); GameEventMail mail; mail.raceMask = fields[1].GetUInt32(); mail.questId = fields[2].GetUInt32(); mail.mailTemplateId = fields[3].GetUInt32(); mail.senderEntry = fields[4].GetUInt32(); if (event_id == 0) { sLog.outErrorDb("`game_event_mail` game event id (%i) not allowed", event_id); continue; } if (!IsValidEvent(event_id)) { sLog.outErrorDb("`game_event_mail` game event id (%u) not exist in `game_event`", event_id); continue; } int32 internal_event_id = mGameEvent.size() + event_id - 1; if (!(mail.raceMask & RACEMASK_ALL_PLAYABLE)) { sLog.outErrorDb("Table `game_event_mail` have raceMask (%u) requirement for game event %i that not include any player races, ignoring.", mail.raceMask, event_id); continue; } if (mail.questId && !sObjectMgr.GetQuestTemplate(mail.questId)) { sLog.outErrorDb("Table `game_event_mail` have nonexistent quest (%u) requirement for game event %i, ignoring.", mail.questId, event_id); continue; } if (!sMailTemplateStore.LookupEntry(mail.mailTemplateId)) { sLog.outErrorDb("Table `game_event_mail` have invalid mailTemplateId (%u) for game event %i that invalid not include any player races, ignoring.", mail.mailTemplateId, event_id); continue; } if (!ObjectMgr::GetCreatureTemplate(mail.senderEntry)) { sLog.outErrorDb("Table `game_event_mail` have nonexistent sender creature entry (%u) for game event %i that invalid not include any player races, ignoring.", mail.senderEntry, event_id); continue; } ++count; MailList& maillist = mGameEventMails[internal_event_id]; maillist.push_back(mail); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString(">> Loaded %u start/end game event mails", count ); } }
void DungeonResetScheduler::LoadResetTimes() { time_t now = time(NULL); time_t today = (now / DAY) * DAY; time_t oldest_reset_time = now; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::pair<uint32 /*PAIR32(map,difficulty)*/, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; QueryResult *result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance WHERE resettime > 0"); if( result ) { do { if(time_t resettime = time_t((*result)[3].GetUInt64())) { uint32 id = (*result)[0].GetUInt32(); uint32 mapid = (*result)[1].GetUInt32(); uint32 difficulty = (*result)[2].GetUInt32(); instResetTime[id] = ResetTimeMapDiffType(MAKE_PAIR32(mapid,difficulty), resettime); } } while (result->NextRow()); delete result; // update reset time for normal instances with the max creature respawn time + X hours result = CharacterDatabase.Query("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); if( result ) { do { Field *fields = result->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt64() + 2 * HOUR); InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if(itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); delete result; } // schedule the reset times for(InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if(itr->second.second > now) ScheduleReset(true, itr->second.second, DungeonResetEvent(RESET_EVENT_NORMAL_DUNGEON, PAIR32_LOPART(itr->second.first),Difficulty(PAIR32_HIPART(itr->second.first)),itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld.getConfig(CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR) * HOUR; result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if(result) { do { Field *fields = result->Fetch(); uint32 mapid = fields[0].GetUInt32(); Difficulty difficulty = Difficulty(fields[1].GetUInt32()); uint64 oldresettime = fields[2].GetUInt64(); MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); if(!mapDiff) { sLog.outError("MapPersistentStateManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid,difficulty); continue; } // update the reset time if the hour in the configs changes time_t offset = sMapStore.LookupEntry(mapid)->instanceResetOffset; uint64 start_point = INSTANCE_RESET_SCHEDULE_START_TIME + offset + diff; uint64 newresettime = start_point + uint32((oldresettime - start_point) / DAY) * DAY; if(oldresettime != newresettime && newresettime > now) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty = '%u'", newresettime, mapid, difficulty); SetResetTimeFor(mapid,difficulty,newresettime); } while(result->NextRow()); delete result; } // clean expired instances, references to them will be deleted in CleanupInstances // must be done before calculating new reset times m_InstanceSaves._CleanupExpiredInstancesAtTime(now); // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for(MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapid = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficulty const* mapDiff = &itr->second; // skip mapDiff without global reset time if (!mapDiff->resetTime) continue; uint32 period = GetMaxResetTimeFor(mapDiff); time_t t = GetResetTimeFor(mapid,difficulty); if(!t || t < now) { bool existsInDB = bool(t); uint32 offset = sMapStore.LookupEntry(mapid)->instanceResetOffset; uint64 start_point = INSTANCE_RESET_SCHEDULE_START_TIME + offset + diff; t = start_point + uint32(ceil(float(now - start_point) / period) * period); if(existsInDB) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); else CharacterDatabase.DirectPExecute("REPLACE INTO instance_reset VALUES ('%u','%u','"UI64FMTD"')", mapid, difficulty, (uint64)t); } SetResetTimeFor(mapid,difficulty,t); // schedule the global reset/warning ResetEventType type = RESET_EVENT_INFORM_1; for(; type < RESET_EVENT_INFORM_LAST; type = ResetEventType(type+1)) if(t - resetEventTypeDelay[type] > now) break; ScheduleReset(true, t - resetEventTypeDelay[type], DungeonResetEvent(type, mapid, difficulty, 0)); } }
void PlayerAchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult) { if (achievementResult) { do { Field* fields = achievementResult->Fetch(); uint32 achievementid = fields[0].GetUInt32(); // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements() AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementid); if (!achievement) continue; CompletedAchievementData& ca = _completedAchievements[achievementid]; ca.Date = time_t(fields[1].GetUInt32()); ca.Changed = false; _achievementPoints += achievement->Points; // title achievement rewards are retroactive if (AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement)) if (uint32 titleId = reward->TitleId[Player::TeamForRace(_owner->getRace()) == ALLIANCE ? 0 : 1]) if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) _owner->SetTitle(titleEntry); } while (achievementResult->NextRow()); } if (criteriaResult) { time_t now = time(NULL); do { Field* fields = criteriaResult->Fetch(); uint32 id = fields[0].GetUInt32(); uint64 counter = fields[1].GetUInt64(); time_t date = time_t(fields[2].GetUInt32()); Criteria const* criteria = sCriteriaMgr->GetCriteria(id); if (!criteria) { // Removing non-existing criteria data for all characters TC_LOG_ERROR("criteria.achievement", "Non-existing achievement criteria %u data has been removed from the table `character_achievement_progress`.", id); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA); stmt->setUInt32(0, id); CharacterDatabase.Execute(stmt); continue; } if (criteria->Entry->StartTimer && time_t(date + criteria->Entry->StartTimer) < now) continue; CriteriaProgress& progress = _criteriaProgress[id]; progress.Counter = counter; progress.Date = date; progress.Changed = false; } while (criteriaResult->NextRow()); } }
void GroupMgr::LoadGroups() { { uint32 oldMSTime = getMSTime(); // Delete all groups whose leader does not exist CharacterDatabase.DirectExecute("DELETE FROM groups WHERE leaderGuid NOT IN (SELECT guid FROM characters)"); // Delete all groups with less than 2 members CharacterDatabase.DirectExecute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)"); // 0 1 2 3 4 5 6 7 8 9 QueryResult result = CharacterDatabase.PQuery("SELECT leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6" // 10 11 12 13 14 15 ", icon7, icon8, groupType, difficulty, raiddifficulty, guid FROM groups ORDER BY guid ASC"); if (!result) { sLog->outString(">> Loaded 0 group definitions. DB table `groups` is empty!"); sLog->outString(); return; } uint32 count = 0; do { Field* fields = result->Fetch(); Group* group = new Group; group->LoadGroupFromDB(fields); AddGroup(group); // Get the ID used for storing the group in the database and register it in the pool. uint32 storageId = group->GetDbStoreId(); RegisterGroupDbStoreId(storageId, group); // Increase the next available storage ID if (storageId == NextGroupDbStoreId) NextGroupDbStoreId++; ++count; } while (result->NextRow()); sLog->outString(">> Loaded %u group definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); } sLog->outString("Loading Group members..."); { uint32 oldMSTime = getMSTime(); // Delete all rows from group_member or group_instance with no group CharacterDatabase.DirectExecute("DELETE FROM group_member WHERE guid NOT IN (SELECT guid FROM groups)"); CharacterDatabase.DirectExecute("DELETE FROM group_instance WHERE guid NOT IN (SELECT guid FROM groups)"); // Delete all members that does not exist CharacterDatabase.DirectExecute("DELETE FROM group_member WHERE memberGuid NOT IN (SELECT guid FROM characters)"); // 0 1 2 3 4 QueryResult result = CharacterDatabase.Query("SELECT guid, memberGuid, memberFlags, subgroup, roles FROM group_member ORDER BY guid"); if (!result) { sLog->outString(">> Loaded 0 group members. DB table `group_member` is empty!"); sLog->outString(); return; } uint32 count = 0; do { Field* fields = result->Fetch(); Group* group = GetGroupByDbStoreId(fields[0].GetUInt32()); if (group) group->LoadMemberFromDB(fields[1].GetUInt32(), fields[2].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt8()); else sLog->outError("GroupMgr::LoadGroups: Consistency failed, can't find group (storage id: %u)", fields[0].GetUInt32()); ++count; } while (result->NextRow()); sLog->outString(">> Loaded %u group members in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); } sLog->outString("Loading Group instance saves..."); { uint32 oldMSTime = getMSTime(); // 0 1 2 3 4 5 6 QueryResult result = CharacterDatabase.Query("SELECT gi.guid, i.map, gi.instance, gi.permanent, i.difficulty, i.resettime, COUNT(g.guid) " "FROM group_instance gi INNER JOIN instance i ON gi.instance = i.id " "LEFT JOIN character_instance ci LEFT JOIN groups g ON g.leaderGuid = ci.guid ON ci.instance = gi.instance AND ci.permanent = 1 GROUP BY gi.instance ORDER BY gi.guid"); if (!result) { sLog->outString(">> Loaded 0 group-instance saves. DB table `group_instance` is empty!"); sLog->outString(); return; } uint32 count = 0; do { Field* fields = result->Fetch(); Group* group = GetGroupByDbStoreId(fields[0].GetUInt32()); // group will never be NULL (we have run consistency sql's before loading) MapEntry const* mapEntry = sMapStore.LookupEntry(fields[1].GetUInt32()); if (!mapEntry || !mapEntry->IsDungeon()) { sLog->outErrorDb("Incorrect entry in group_instance table : no dungeon map %d", fields[1].GetUInt32()); continue; } uint32 diff = fields[4].GetUInt8(); if (diff >= uint32(mapEntry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY)) { sLog->outErrorDb("Wrong dungeon difficulty use in group_instance table: %d", diff + 1); diff = 0; // default for both difficaly types } InstanceSave* save = sInstanceSaveMgr->AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), Difficulty(diff), time_t(fields[5].GetUInt64()), fields[6].GetBool(), true); group->BindToInstance(save, fields[3].GetBool(), true); ++count; } while (result->NextRow()); sLog->outString(">> Loaded %u group-instance saves in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); } }
void Database::Statement::value(int column, Time &v) const { int64_t t = 0; value(column, t); v = time_t(t); }
void InstanceSaveManager::LoadResetTimes() { time_t now = time(NULL); time_t today = (now / DAY) * DAY; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::map<uint32, std::pair<uint32, time_t> > ResetTimeMapType; ResetTimeMapType InstResetTime; QueryResult *result = CharacterDatabase.Query("SELECT id, map, resettime FROM instance WHERE resettime > 0"); if( result ) { do { if(time_t resettime = time_t((*result)[2].GetUInt64())) { uint32 id = (*result)[0].GetUInt32(); uint32 mapid = (*result)[1].GetUInt32(); InstResetTime[id] = std::pair<uint32, uint64>(mapid, resettime); } } while (result->NextRow()); delete result; // update reset time for normal instances with the max creature respawn time + X hours result = WorldDatabase.Query("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); if( result ) { do { Field *fields = result->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt64() + 2 * HOUR); ResetTimeMapType::iterator itr = InstResetTime.find(instance); if(itr != InstResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); delete result; } // schedule the reset times for(ResetTimeMapType::iterator itr = InstResetTime.begin(); itr != InstResetTime.end(); ++itr) if(itr->second.second > now) ScheduleReset(true, itr->second.second, InstResetEvent(0, itr->second.first, itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; m_resetTimeByMapId.resize(sMapStore.GetNumRows()+1); result = CharacterDatabase.Query("SELECT mapid, resettime FROM instance_reset"); if(result) { do { Field *fields = result->Fetch(); uint32 mapid = fields[0].GetUInt32(); if(!objmgr.GetInstanceTemplate(mapid)) { sLog.outError("InstanceSaveManager::LoadResetTimes: invalid mapid %u in instance_reset!", mapid); CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u'", mapid); continue; } // update the reset time if the hour in the configs changes uint64 oldresettime = fields[1].GetUInt64(); uint64 newresettime = (oldresettime / DAY) * DAY + diff; if(oldresettime != newresettime) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u'", newresettime, mapid); m_resetTimeByMapId[mapid] = newresettime; } while(result->NextRow()); delete result; } // clean expired instances, references to them will be deleted in CleanupInstances // must be done before calculating new reset times _DelHelper(CharacterDatabase, "id, map, difficulty", "instance", "LEFT JOIN instance_reset ON mapid = map WHERE (instance.resettime < '"UI64FMTD"' AND instance.resettime > '0') OR (NOT instance_reset.resettime IS NULL AND instance_reset.resettime < '"UI64FMTD"')", (uint64)now, (uint64)now); // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++) { InstanceTemplate const* temp = objmgr.GetInstanceTemplate(i); if(!temp) continue; // only raid/heroic maps have a global reset time const MapEntry* entry = sMapStore.LookupEntry(temp->map); if(!entry || !entry->HasResetTime()) continue; uint32 period = temp->reset_delay * DAY; assert(period != 0); time_t t = m_resetTimeByMapId[temp->map]; if(!t) { // initialize the reset time t = today + period + diff; CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','"UI64FMTD"')", i, (uint64)t); } if(t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u'", (uint64)t, i); } m_resetTimeByMapId[temp->map] = t; // schedule the global reset/warning uint8 type = 1; static int tim[4] = {3600, 900, 300, 60}; for(; type < 4; type++) if(t - tim[type-1] > now) break; ScheduleReset(true, t - tim[type-1], InstResetEvent(type, i)); } }
/// Explicit conversion into time_t. constexpr time_t seconds_since_epoch() const noexcept { return time_t(m_timestamp); }
int main ( int argc, char **argv ) { //FILE *testarena; char tempstr[256]; setDefaultLogName("rapicDS.log"); RapicStartedTime = time(0); mainpid = getpid(); sprintf(arenaname,"%s.arena",argv[0]); sprintf(Title,"%s %s",argv[0], versionStr()); sprintf(tempstr,"%s - Starting as pid %d\n",Title, mainpid); RapicLog(tempstr, LOG_WARNING); init_signals(); if (FileExists("rapicquitflag", true, true)) { sprintf(tempstr,"%s - Warning - rapicquitflag detected on startup, deleting",Title); RapicLog(tempstr, LOG_WARNING); } #ifdef THREAD_SPROC usptr_t *arena = 0; if (testarena = fopen(arenaname,"r")) { fprintf(stderr,"WARNING - IRIX ARENA ALREADY EXISTS - %s\n",arenaname); // fprintf(stderr,"FATAL ERROR - 3D Rapic CANNOT RUN"); // exit(-1); } else fclose(testarena); int ret; if (ret = usconfig(CONF_INITSIZE,256000)) { perror("usconfig(CONF_INITSIZE)"); }; if (ret = usconfig(CONF_LOCKTYPE,US_DEBUGPLUS)) { perror("usconfig(CONF_LOCKTYPE)"); }; // usconfig(CONF_LOCKTYPE,US_DEBUG); // usconfig(CONF_LOCKTYPE,US_NODEBUG); if (ret = usconfig(CONF_ARENATYPE,US_SHAREDONLY)) { perror("usconfig(CONF_ARENATYPE)"); }; if (ret = usconfig(CONF_INITUSERS,150)) { perror("usconfig(CONF_INITUSERS)"); }; // usconfig(CONF_STHREADIOOFF); if (!(arena = usinit(arenaname))) { fprintf(stderr,"usinit(%s) - FAILED ", arenaname); perror(0); fprintf(stderr,"FATAL ERROR - %s CANNOT RUN", argv[0]); exit(-1); } #endif GetSiteInfo(DISABLE_COVERAGE_LOAD); FreeListMng = new free_list_mng; ScanMng = new scan_mng; rpdbCacheCopyMode = argFound(argc, argv, "cache_path"); if (InitISAM(10,30,12)) fprintf(stderr,"CTree InitISAM ERROR"); else { DBMngr = new DBMng(!rpdbCacheCopyMode); // don't allow db purge if cache copy mode if (DBMngr) { if (ScanMng) { ScanMng->AddClient(DBMngr); if ((ScanMng->recentCachePeriod > 0) && ScanMng->keepScansInCache) { fprintf(stdout, "Loading last %dmins of data from database into recent scan cache\n", ScanMng->recentCachePeriod); DBMngr->loadInitialSeq(NULL, 1, true); ScanMng->startupLatestTime = ScanMng->mostRecentScanTime(); //latest time from db on startup ScanMng->PrintScanUsage(stdout, true); } } } } CommMngr = new RPCommMng; if (FileExists(defaultreplayinifile)) { if (ReplayMngr) { delete ReplayMngr; ReplayMngr = 0; } ReplayMngr = new replay(defaultreplayinifile); } if (FileExists("nexrad.ini")) { NexRadManager = new NexRadMgr(); if (NexRadManager) { NexRadManager->StartNexRadStnHdlrs(); } } if (FileExists("uf.ini")) { ufManager = new ufMgr(); if (ufManager) { ufManager->StartUfStnHdlrs(); } } if (FileExists("fileReaders.ini")) initGlobalFileReaderMng(argv[0], "fileReaders.ini"); check_rpdbCacheCopyMode(argc, argv); if (DBMngr && DBMngr->rpdbCache && cacheCopyReq) { if (rpdbCacheStatsMode) { DBMngr->rpdbCache->dumpCacheContents("rpdb_cache_contents.txt"); DBMngr->rpdbCache->dumpStats(*cacheCopyReq, "cache_stats.txt"); } else if (rpdbCacheCopyMode) { DBMngr->rpdbCache->dumpCacheContents("rpdb_cache_contents.txt"); DBMngr->rpdbCache->copyDB(*cacheCopyReq); } } while (!quitRapicConvert && !rpdbCacheCopyMode) { timenow = time(0); if (CommMngr) { if (time(0) >= NextCommPollTime) { CommMngr->CheckComms(); NextCommPollTime = timenow + CommPollPeriod; } } if (DBMngr && (timenow > DBMngr->DBCheckTime)) { if (DBMngr->CheckScans()) // false if scan check not yet complete DBMngr->DBCheckTime = timenow + DBMngr->DBCheckPeriod; } if (ReplayMngr && (timenow > ReplayCheckTime)) { ReplayMngr->check_replay(); ReplayCheckTime = timenow + time_t(float(ReplayCheckPeriod)/ReplayMngr->getTimeScale()); } if (ScanMng && (timenow > ScanMng->CheckTime)) ScanMng->Check(); if (reqMemCheck || (MemoryStatusDumpTime <= timenow) || FileExists("memdump.flag", 1, 1)) { AppendMemoryStatus(); MemoryStatusDumpTime = time(0) + MemoryStatusDumpPeriod; reqMemCheck = false; } sec_delay(0.5); if (FileExists("rapicquitflag", true, false)) { quitRapicConvert = true; fprintf(stdout,"%s - Detected rapicquitflag - Shutting down - pid %d",Title, mainpid); } } fprintf(stdout,"%s - Shutting down - pid %d",Title, mainpid); if (CommMngr) { delete CommMngr; CommMngr = 0; } if (ufManager) { delete ufManager; ufManager = 0; } if (NexRadManager) { delete NexRadManager; NexRadManager = 0; } if (DBMngr) { delete DBMngr; DBMngr = 0; } if (ScanMng) { delete ScanMng; ScanMng = 0; } if (ReplayMngr) { delete ReplayMngr; ReplayMngr = 0; } closeGlobalFileReaderMng(); if (FileExists("rapicquitflag", true, true)) { fprintf(stdout,"%s - Shut down complete - pid %d - Removing rapicquitflag",Title, mainpid); } return 0; }
static bool HandleBanListIPCommand(ChatHandler* handler, char const* args) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); LoginDatabase.Execute(stmt); char* filterStr = strtok((char*)args, " "); std::string filter = filterStr ? filterStr : ""; LoginDatabase.EscapeString(filter); PreparedQueryResult result; if (filter.empty()) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_ALL); result = LoginDatabase.Query(stmt); } else { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_BY_IP); stmt->setString(0, filter); result = LoginDatabase.Query(stmt); } if (!result) { handler->PSendSysMessage(LANG_BANLIST_NOIP); return true; } handler->PSendSysMessage(LANG_BANLIST_MATCHINGIP); // Chat short output if (handler->GetSession()) { do { Field* fields = result->Fetch(); handler->PSendSysMessage("%s", fields[0].GetCString()); } while (result->NextRow()); } // Console wide output else { handler->SendSysMessage(LANG_BANLIST_IPS); handler->SendSysMessage(" ==============================================================================="); handler->SendSysMessage(LANG_BANLIST_IPS_HEADER); do { handler->SendSysMessage("-------------------------------------------------------------------------------"); Field* fields = result->Fetch(); time_t timeBan = time_t(fields[1].GetUInt32()); tm* tmBan = localtime(&timeBan); if (fields[1].GetUInt32() == fields[2].GetUInt32()) { handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", fields[0].GetCString(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, fields[3].GetCString(), fields[4].GetCString()); } else { time_t timeUnban = time_t(fields[2].GetUInt32()); tm* tmUnban = localtime(&timeUnban); handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", fields[0].GetCString(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min, fields[3].GetCString(), fields[4].GetCString()); } } while (result->NextRow()); handler->SendSysMessage(" ==============================================================================="); } return true; }
static bool HandleBanListCharacterCommand(ChatHandler* handler, char const* args) { if (!*args) return false; char* filterStr = strtok((char*)args, " "); if (!filterStr) return false; std::string filter(filterStr); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME_FILTER); stmt->setString(0, filter); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_BANLIST_NOCHARACTER); return true; } handler->PSendSysMessage(LANG_BANLIST_MATCHINGCHARACTER); // Chat short output if (handler->GetSession()) { do { Field* fields = result->Fetch(); PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_BANNED_NAME); stmt2->setUInt32(0, fields[0].GetUInt32()); PreparedQueryResult banResult = CharacterDatabase.Query(stmt2); if (banResult) handler->PSendSysMessage("%s", (*banResult)[0].GetCString()); } while (result->NextRow()); } // Console wide output else { handler->SendSysMessage(LANG_BANLIST_CHARACTERS); handler->SendSysMessage(" =============================================================================== "); handler->SendSysMessage(LANG_BANLIST_CHARACTERS_HEADER); do { handler->SendSysMessage("-------------------------------------------------------------------------------"); Field* fields = result->Fetch(); std::string char_name = fields[1].GetString(); PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_BANINFO_LIST); stmt2->setUInt32(0, fields[0].GetUInt32()); PreparedQueryResult banInfo = CharacterDatabase.Query(stmt2); if (banInfo) { Field* banFields = banInfo->Fetch(); do { time_t timeBan = time_t(banFields[0].GetUInt32()); tm* tmBan = localtime(&timeBan); if (banFields[0].GetUInt32() == banFields[1].GetUInt32()) { handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", char_name.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, banFields[2].GetCString(), banFields[3].GetCString()); } else { time_t timeUnban = time_t(banFields[1].GetUInt32()); tm* tmUnban = localtime(&timeUnban); handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", char_name.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min, banFields[2].GetCString(), banFields[3].GetCString()); } } while (banInfo->NextRow()); } } while (result->NextRow()); handler->SendSysMessage(" =============================================================================== "); } return true; }
uint TSecTm::GetDSecs(const TSecTm& SecTm1, const TSecTm& SecTm2){ IAssert(SecTm1.IsDef()&&SecTm2.IsDef()); const time_t Time1= time_t(SecTm1.AbsSecs()); const time_t Time2= time_t(SecTm2.AbsSecs()); return uint(difftime(Time2, Time1)); }
void CalendarMgr::LoadFromDB() { uint32 count = 0; _maxEventId = 0; _maxInviteId = 0; // 0 1 2 3 4 5 6 7 8 if (QueryResult result = CharacterDatabase.Query("SELECT id, creator, title, description, type, dungeon, eventtime, flags, time2 FROM calendar_events")) do { Field* fields = result->Fetch(); uint64 eventId = fields[0].GetUInt64(); uint64 creatorGUID = MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER); std::string title = fields[2].GetString(); std::string description = fields[3].GetString(); CalendarEventType type = CalendarEventType(fields[4].GetUInt8()); int32 dungeonId = fields[5].GetInt32(); uint32 eventTime = fields[6].GetUInt32(); uint32 flags = fields[7].GetUInt32(); uint32 timezoneTime = fields[8].GetUInt32(); uint32 guildId = 0; if (flags & CALENDAR_FLAG_GUILD_EVENT || flags & CALENDAR_FLAG_WITHOUT_INVITES) guildId = Player::GetGuildIdFromDB(creatorGUID); CalendarEvent* calendarEvent = new CalendarEvent(eventId, creatorGUID, guildId, type, dungeonId, time_t(eventTime), flags, time_t(timezoneTime), title, description); _events.insert(calendarEvent); _maxEventId = std::max(_maxEventId, eventId); ++count; } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u calendar events", count); count = 0; // 0 1 2 3 4 5 6 7 if (QueryResult result = CharacterDatabase.Query("SELECT id, event, invitee, sender, status, statustime, rank, text FROM calendar_invites")) do { Field* fields = result->Fetch(); uint64 inviteId = fields[0].GetUInt64(); uint64 eventId = fields[1].GetUInt64(); uint64 invitee = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); uint64 senderGUID = MAKE_NEW_GUID(fields[3].GetUInt32(), 0, HIGHGUID_PLAYER); CalendarInviteStatus status = CalendarInviteStatus(fields[4].GetUInt8()); uint32 statusTime = fields[5].GetUInt32(); CalendarModerationRank rank = CalendarModerationRank(fields[6].GetUInt8()); std::string text = fields[7].GetString(); CalendarInvite* invite = new CalendarInvite(inviteId, eventId, invitee, senderGUID, time_t(statusTime), status, rank, text); _invites[eventId].push_back(invite); _maxInviteId = std::max(_maxInviteId, inviteId); ++count; } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u calendar invites", count); for (uint64 i = 1; i < _maxEventId; ++i) if (!GetEvent(i)) _freeEventIds.push_back(i); for (uint64 i = 1; i < _maxInviteId; ++i) if (!GetInvite(i)) _freeInviteIds.push_back(i); }
void GameEvent::LoadFromDB() { { QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM game_event"); if( !result ) { sLog.outString(">> Table game_event is empty."); sLog.outString(); return; } Field *fields = result->Fetch(); uint32 max_event_id = fields[0].GetUInt16(); delete result; mGameEvent.resize(max_event_id+1); } QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,description FROM game_event"); if( !result ) { mGameEvent.clear(); sLog.outString(">> Table game_event is empty!"); sLog.outString(); return; } uint32 count = 0; { barGoLink bar( result->GetRowCount() ); do { ++count; Field *fields = result->Fetch(); bar.step(); uint16 event_id = fields[0].GetUInt16(); if(event_id==0) { sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id); continue; } GameEventData& pGameEvent = mGameEvent[event_id]; uint64 starttime = fields[1].GetUInt64(); pGameEvent.start = time_t(starttime); uint64 endtime = fields[2].GetUInt64(); pGameEvent.end = time_t(endtime); pGameEvent.occurence = fields[3].GetUInt32(); pGameEvent.length = fields[4].GetUInt32(); if(pGameEvent.length==0) // length>0 is validity check { sLog.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id); continue; } pGameEvent.description = fields[5].GetCppString(); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u game events", count ); } mGameEventCreatureGuids.resize(mGameEvent.size()*2-1); // 1 2 result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event " "FROM creature JOIN game_event_creature ON creature.guid = game_event_creature.guid"); count = 0; if( !result ) { barGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u creatures in game events", count ); } else { barGoLink bar( result->GetRowCount() ); do { Field *fields = result->Fetch(); bar.step(); uint32 guid = fields[0].GetUInt32(); int16 event_id = fields[1].GetInt16(); int32 internal_event_id = mGameEvent.size() + event_id - 1; if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size()) { sLog.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id); continue; } ++count; GuidList& crelist = mGameEventCreatureGuids[internal_event_id]; crelist.push_back(guid); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u creatures in game events", count ); } mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1); // 1 2 result = WorldDatabase.Query("SELECT gameobject.guid, game_event_gameobject.event " "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid"); count = 0; if( !result ) { barGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u gameobjects in game events", count ); } else { barGoLink bar( result->GetRowCount() ); do { Field *fields = result->Fetch(); bar.step(); uint32 guid = fields[0].GetUInt32(); int16 event_id = fields[1].GetInt16(); int32 internal_event_id = mGameEvent.size() + event_id - 1; if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size()) { sLog.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id); continue; } ++count; GuidList& golist = mGameEventGameobjectGuids[internal_event_id]; golist.push_back(guid); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u gameobjects in game events", count ); } mGameEventModelEquip.resize(mGameEvent.size()); // 0 1 2 result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid," // 3 "game_event_model_equip.equipment_id " "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid"); count = 0; if( !result ) { barGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u model/equipment changes in game events", count ); } else { barGoLink bar( result->GetRowCount() ); do { Field *fields = result->Fetch(); bar.step(); uint32 guid = fields[0].GetUInt32(); uint16 event_id = fields[1].GetUInt16(); if(event_id >= mGameEventModelEquip.size()) { sLog.outErrorDb("`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`",event_id); continue; } ++count; ModelEquipList& equiplist = mGameEventModelEquip[event_id]; ModelEquip newModelEquipSet; newModelEquipSet.modelid = fields[2].GetUInt32(); newModelEquipSet.equipment_id = fields[3].GetUInt32(); newModelEquipSet.equipement_id_prev = 0; newModelEquipSet.modelid_prev = 0; if(newModelEquipSet.equipment_id > 0) { if(!objmgr.GetEquipmentInfo(newModelEquipSet.equipment_id)) { sLog.outErrorDb("Table `game_event_model_equip` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", guid, newModelEquipSet.equipment_id); continue; } } equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet)); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u model/equipment changes in game events", count ); } mGameEventQuests.resize(mGameEvent.size()); // 0 1 2 result = WorldDatabase.Query("SELECT id, quest, event FROM game_event_creature_quest"); count = 0; if( !result ) { barGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded %u quests additions in game events", count ); } else { barGoLink bar( result->GetRowCount() ); do { Field *fields = result->Fetch(); bar.step(); uint32 id = fields[0].GetUInt32(); uint32 quest = fields[1].GetUInt32(); uint16 event_id = fields[2].GetUInt16(); if(event_id >= mGameEventQuests.size()) { sLog.outErrorDb("`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id); continue; } ++count; QuestRelList& questlist = mGameEventQuests[event_id]; questlist.push_back(QuestRelation(id, quest)); } while( result->NextRow() ); delete result; sLog.outString(); sLog.outString( ">> Loaded %u quests additions in game events", count ); } mGameEventPoolIds.resize(mGameEvent.size()*2-1); // 1 2 result = WorldDatabase.Query("SELECT pool_template.entry, game_event_pool.event " "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry"); count = 0; if( !result ) { barGoLink bar2(1); bar2.step(); sLog.outString(); sLog.outString(">> Loaded %u pools in game events", count ); } else { barGoLink bar2( result->GetRowCount() ); do { Field *fields = result->Fetch(); bar2.step(); uint32 entry = fields[0].GetUInt16(); int16 event_id = fields[1].GetInt16(); int32 internal_event_id = mGameEvent.size() + event_id - 1; if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size()) { sLog.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id); continue; } if (!poolhandler.CheckPool(entry)) { sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry); continue; } ++count; IdList& poollist = mGameEventPoolIds[internal_event_id]; poollist.push_back(entry); } while( result->NextRow() ); sLog.outString(); sLog.outString( ">> Loaded %u pools in game events", count ); delete result; } }
void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) { uint64 guid = _player->GetGUID(); std::string title; std::string description; uint8 type; int32 dungeonId; uint32 eventPackedTime; uint32 maxInvites; // always 100, necesary? Not find the way how to change it uint32 flags; uint32 inviteeCount; uint16 descriptionLength, titleLength; recvData >> maxInvites >> flags >> dungeonId; recvData.ReadPackedTime(eventPackedTime); recvData >> type; inviteeCount = recvData.ReadBits(22); descriptionLength = recvData.ReadBits(11); std::list<CalendarInvitePacketInfo> calendarInviteList; for (uint32 i = 0; i < inviteeCount; i++) { CalendarInvitePacketInfo info; info.Guid[7] = recvData.ReadBit(); info.Guid[2] = recvData.ReadBit(); info.Guid[6] = recvData.ReadBit(); info.Guid[3] = recvData.ReadBit(); info.Guid[5] = recvData.ReadBit(); info.Guid[1] = recvData.ReadBit(); info.Guid[0] = recvData.ReadBit(); info.Guid[4] = recvData.ReadBit(); calendarInviteList.push_back(info); } titleLength = recvData.ReadBits(8); for (std::list<CalendarInvitePacketInfo>::iterator iter = calendarInviteList.begin(); iter != calendarInviteList.end(); ++iter) { recvData.ReadByteSeq(iter->Guid[4]); recvData.ReadByteSeq(iter->Guid[2]); recvData.ReadByteSeq(iter->Guid[3]); recvData.ReadByteSeq(iter->Guid[1]); recvData.ReadByteSeq(iter->Guid[0]); recvData.ReadByteSeq(iter->Guid[6]); recvData.ReadByteSeq(iter->Guid[7]); recvData >> iter->Status; recvData.ReadByteSeq(iter->Guid[5]); recvData >> iter->ModerationRank; } title = recvData.ReadString(titleLength); description = recvData.ReadString(descriptionLength); CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId, time_t(eventPackedTime), flags, title, description); if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement()) if (Player* creator = ObjectAccessor::FindPlayer(guid)) calendarEvent->SetGuildId(creator->GetGuildId()); if (calendarEvent->IsGuildAnnouncement()) { // DEFAULT_STATUS_TIME is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(0, calendarEvent->GetEventId(), 0, guid, DEFAULT_STATUS_TIME, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->AddInvite(calendarEvent, invite); } else { for (std::list<CalendarInvitePacketInfo>::const_iterator iter = calendarInviteList.begin(); iter != calendarInviteList.end(); ++iter) { // DEFAULT_STATUS_TIME is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), (uint64)iter->Guid, guid, DEFAULT_STATUS_TIME, CalendarInviteStatus(iter->Status), CalendarModerationRank(iter->ModerationRank), ""); sCalendarMgr->AddInvite(calendarEvent, invite); } } sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD); }
void MapPersistentStateManager::LoadGameobjectRespawnTimes() { // remove outdated data CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())"); uint32 count = 0; QueryResult *result = CharacterDatabase.Query("SELECT guid, respawntime, map, instance, difficulty, resettime FROM gameobject_respawn LEFT JOIN instance ON instance = id"); if(!result) { barGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded 0 gameobject respawn time."); return; } barGoLink bar((int)result->GetRowCount()); do { Field *fields = result->Fetch(); bar.step(); uint32 loguid = fields[0].GetUInt32(); uint64 respawn_time = fields[1].GetUInt64(); uint32 mapId = fields[2].GetUInt32(); uint32 instanceId = fields[3].GetUInt32(); uint8 difficulty = fields[4].GetUInt8(); time_t resetTime = (time_t)fields[5].GetUInt64(); GameObjectData const* data = sObjectMgr.GetGOData(loguid); if (!data) continue; if (mapId != data->mapid) continue; MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); if (!mapEntry || (mapEntry->Instanceable() != (instanceId != 0))) continue; if(difficulty >= (!mapEntry->Instanceable() ? REGULAR_DIFFICULTY : (mapEntry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY))) continue; MapPersistentState* state = AddPersistentState(mapEntry, instanceId, Difficulty(difficulty), resetTime, mapEntry->IsDungeon(), true); if (!state) continue; state->SetGORespawnTime(loguid, time_t(respawn_time)); ++count; } while (result->NextRow()); delete result; sLog.outString(">> Loaded %u gameobject respawn times", count); sLog.outString(); }
void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData) { uint64 guid = _player->GetGUID(); time_t oldEventTime; ObjectGuid eventId; ObjectGuid inviteId; std::string title; std::string description; uint8 type; uint32 maxInvites; int32 dungeonId; uint32 eventPackedTime; uint32 flags; uint16 descriptionLength; uint16 titleLength; recvData >> maxInvites >> dungeonId; recvData.ReadPackedTime(eventPackedTime); recvData >> flags >> type; eventId[4] = recvData.ReadBit(); eventId[5] = recvData.ReadBit(); eventId[2] = recvData.ReadBit(); inviteId[4] = recvData.ReadBit(); eventId[7] = recvData.ReadBit(); eventId[0] = recvData.ReadBit(); inviteId[5] = recvData.ReadBit(); inviteId[3] = recvData.ReadBit(); eventId[6] = recvData.ReadBit(); eventId[1] = recvData.ReadBit(); inviteId[6] = recvData.ReadBit(); inviteId[2] = recvData.ReadBit(); inviteId[7] = recvData.ReadBit(); inviteId[1] = recvData.ReadBit(); inviteId[0] = recvData.ReadBit(); descriptionLength = recvData.ReadBits(11); titleLength = recvData.ReadBits(8); eventId[3] = recvData.ReadBit(); recvData.ReadByteSeq(inviteId[6]); recvData.ReadByteSeq(eventId[0]); recvData.ReadByteSeq(inviteId[7]); recvData.ReadByteSeq(inviteId[3]); recvData.ReadByteSeq(eventId[6]); recvData.ReadByteSeq(inviteId[1]); recvData.ReadByteSeq(eventId[2]); title = recvData.ReadString(titleLength); recvData.ReadByteSeq(inviteId[5]); recvData.ReadByteSeq(inviteId[4]); recvData.ReadByteSeq(eventId[5]); recvData.ReadByteSeq(eventId[3]); recvData.ReadByteSeq(inviteId[0]); recvData.ReadByteSeq(eventId[4]); description = recvData.ReadString(descriptionLength); recvData.ReadByteSeq(eventId[1]); recvData.ReadByteSeq(inviteId[2]); recvData.ReadByteSeq(eventId[7]); TC_LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [" UI64FMTD "] EventId [" UI64FMTD "], InviteId [" UI64FMTD "] Title %s, Description %s, type %u " "MaxInvites %u, Dungeon ID %d, Time %u, Flags %u", guid, (uint64)eventId, (uint64)inviteId, title.c_str(), description.c_str(), type, maxInvites, dungeonId, eventPackedTime, flags); if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) { oldEventTime = calendarEvent->GetEventTime(); calendarEvent->SetType(CalendarEventType(type)); calendarEvent->SetFlags(flags); calendarEvent->SetEventTime(time_t(eventPackedTime)); calendarEvent->SetDungeonId(dungeonId); calendarEvent->SetTitle(title); calendarEvent->SetDescription(description); sCalendarMgr->UpdateEvent(calendarEvent); sCalendarMgr->SendCalendarEventUpdateAlert(*calendarEvent, oldEventTime); } else sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID); }
bool Corpse::LoadFromDB(uint32 lowguid, Field* fields) { //// 0 1 2 3 4 5 6 // QueryResult *result = CharacterDatabase.Query("SELECT corpse.guid, player, corpse.position_x, corpse.position_y, corpse.position_z, corpse.orientation, corpse.map," //// 7 8 9 10 11 12 13 14 15 16 17 18 // "time, corpse_type, instance, phaseMask, gender, race, class, playerBytes, playerBytes2, equipmentCache, guildId, playerFlags FROM corpse" uint32 playerLowGuid = fields[1].GetUInt32(); WorldLocation position( fields[6].GetUInt32(), //MapId fields[2].GetFloat(), // x fields[3].GetFloat(), // y fields[4].GetFloat(), // z fields[5].GetFloat(), // orientation fields[10].GetUInt32(), // PhaseMask fields[9].GetUInt32()); // InstanceId Object::_Create(ObjectGuid(HIGHGUID_CORPSE, lowguid)); m_time = time_t(fields[7].GetUInt64()); m_type = CorpseType(fields[8].GetUInt32()); if (m_type >= MAX_CORPSE_TYPE) { sLog.outError("%s Owner %s have wrong corpse type (%i), not load.", GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str(), m_type); return false; } uint8 gender = fields[11].GetUInt8(); uint8 race = fields[12].GetUInt8(); uint8 _class = fields[13].GetUInt8(); uint32 playerBytes = fields[14].GetUInt32(); uint32 playerBytes2 = fields[15].GetUInt32(); uint32 guildId = fields[17].GetUInt32(); uint32 playerFlags = fields[18].GetUInt32(); ObjectGuid guid = ObjectGuid(HIGHGUID_CORPSE, lowguid); ObjectGuid playerGuid = ObjectGuid(HIGHGUID_PLAYER, playerLowGuid); // overwrite possible wrong/corrupted guid SetGuidValue(OBJECT_FIELD_GUID, guid); SetGuidValue(CORPSE_FIELD_OWNER, playerGuid); SetObjectScale(DEFAULT_OBJECT_SCALE); PlayerInfo const* info = sObjectMgr.GetPlayerInfo(race, _class); if (!info) { sLog.outError("Player %u has incorrect race/class pair.", GetGUIDLow()); return false; } SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, gender == GENDER_FEMALE ? info->displayId_f : info->displayId_m); // Load equipment Tokens data(fields[16].GetCppString(), ' '); for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot) { uint32 visualbase = slot * 2; uint32 item_id = atoi(data[visualbase]); const ItemPrototype* proto = ObjectMgr::GetItemPrototype(item_id); if (!proto) { SetUInt32Value(CORPSE_FIELD_ITEM + slot, 0); continue; } SetUInt32Value(CORPSE_FIELD_ITEM + slot, proto->DisplayInfoID | (proto->InventoryType << 24)); } uint8 skin = (uint8)(playerBytes); uint8 face = (uint8)(playerBytes >> 8); uint8 hairstyle = (uint8)(playerBytes >> 16); uint8 haircolor = (uint8)(playerBytes >> 24); uint8 facialhair = (uint8)(playerBytes2); SetUInt32Value(CORPSE_FIELD_BYTES_1, ((0x00) | (race << 8) | (gender << 16) | (skin << 24))); SetUInt32Value(CORPSE_FIELD_BYTES_2, ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24))); SetUInt32Value(CORPSE_FIELD_GUILD, guildId); uint32 flags = CORPSE_FLAG_UNK2; if (playerFlags & PLAYER_FLAGS_HIDE_HELM) flags |= CORPSE_FLAG_HIDE_HELM; if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK) flags |= CORPSE_FLAG_HIDE_CLOAK; SetUInt32Value(CORPSE_FIELD_FLAGS, flags); // no need to mark corpse as lootable, because corpses are not saved in battle grounds Relocate(position); if (!IsPositionValid()) { sLog.outError("%s Owner %s not created. Suggested coordinates isn't valid (X: %f Y: %f)", GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str(), GetPositionX(), GetPositionY()); return false; } m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY()); return true; }
void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) { uint64 guid = _player->GetGUID(); std::string title; std::string description; uint8 type; uint8 repeatable; uint32 maxInvites; int32 dungeonId; uint32 eventPackedTime; uint32 unkPackedTime; uint32 flags; recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId; recvData.ReadPackedTime(eventPackedTime); recvData.ReadPackedTime(unkPackedTime); recvData >> flags; CalendarEvent calendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId, time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description); if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement()) if (Player* creator = ObjectAccessor::FindPlayer(guid)) calendarEvent.SetGuildId(creator->GetGuildId()); if (calendarEvent.IsGuildAnnouncement()) { // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite invite(0, calendarEvent.GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, ""); // WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind // of storage of the pointer as it will lead to memory corruption sCalendarMgr->AddInvite(&calendarEvent, &invite); } else { uint32 inviteCount; recvData >> inviteCount; SQLTransaction trans; if (inviteCount > 1) trans = CharacterDatabase.BeginTransaction(); // client limits the amount of players to be invited to 100 const uint32 MaxPlayerInvites = 100; for (uint32 i = 0; i < inviteCount && i < MaxPlayerInvites; ++i) { uint64 invitee = 0; uint8 status = 0; uint8 rank = 0; recvData.readPackGUID(invitee); recvData >> status >> rank; // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent.GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), ""); sCalendarMgr->AddInvite(&calendarEvent, invite, trans); } if (inviteCount > 1) CharacterDatabase.CommitTransaction(trans); } sCalendarMgr->AddEvent(new CalendarEvent(calendarEvent, calendarEvent.GetEventId()), CALENDAR_SENDTYPE_ADD); }
void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recv_data*/) { uint64 guid = _player->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_GET_CALENDAR [" UI64FMTD "]", guid); time_t cur_time = time_t(time(NULL)); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_SEND_CALENDAR [" UI64FMTD "]", guid); WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 4+4*0+4+4*0+4+4); data << uint32(0); // invite count /* for (;;) { uint64 inviteId; uint64 unkGuid0; uint8 unk1, unk2, unk3; uint64 creatorGuid; } */ data << uint32(0); // event count /* for (;;) { uint64 eventId; std::string title; // 128 chars uint32 type; uint32 occurrenceTime; uint32 flags; uint32 unk4; -- possibly mapid for dungeon/raid uint64 creatorGuid; } */ data << uint32(cur_time); // server time data << uint32(secsToTimeBitFields(cur_time)); // server time uint32 counter = 0; size_t p_counter = data.wpos(); data << uint32(counter); // instance save count for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) for (Player::BoundInstancesMap::const_iterator itr = _player->_boundInstances[i].begin(); itr != _player->_boundInstances[i].end(); ++itr) if (itr->second.perm) { InstanceSave const* save = itr->second.save; data << uint32(save->GetMapId()); data << uint32(save->GetDifficulty()); data << uint32(save->GetResetTime() - cur_time); data << uint64(save->GetInstanceId()); // instance save id as unique instance copy id ++counter; } data.put<uint32>(p_counter, counter); data << uint32(1135753200); // unk (28.12.2005 07:00) counter = 0; p_counter = data.wpos(); data << uint32(counter); // raid reset count std::set<uint32> sentMaps; ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap(); for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr) { uint32 mapId = PAIR32_LOPART(itr->first); if (sentMaps.find(mapId) != sentMaps.end()) continue; MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); if (!mapEntry || !mapEntry->IsRaid()) continue; sentMaps.insert(mapId); data << uint32(mapId); data << uint32(itr->second - cur_time); data << uint32(mapEntry->unk_time); ++counter; } data.put<uint32>(p_counter, counter); data << uint32(0); // holiday count? /* for (;;) { uint32 unk5, unk6, unk7, unk8, unk9; for (uint32 j = 0; j < 26; ++j) { uint32 unk10; } for (uint32 j = 0; j < 10; ++j) { uint32 unk11; } for (uint32 j = 0; j < 10; ++j) { uint32 unk12; } std::string holidayName; // 64 chars } */ SendPacket(&data); }
void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime) { // global reset for all instances of the given map MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); if (!mapEntry->Instanceable()) return; time_t now = time(NULL); if (!warn) { MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty); if (!mapDiff || !mapDiff->resetTime) { TC_LOG_ERROR(LOG_FILTER_GENERAL, "InstanceSaveManager::ResetOrWarnAll: not valid difficulty or no reset delay for map %d", mapid); return; } // remove all binds to instances of the given map for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end();) { if (itr->second->GetMapId() == mapid && itr->second->GetDifficulty() == difficulty) _ResetSave(itr); else ++itr; } // delete them from the DB, even if not loaded SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_MAP_DIFF); stmt->setUInt16(0, uint16(mapid)); stmt->setUInt8(1, uint8(difficulty)); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF); stmt->setUInt16(0, uint16(mapid)); stmt->setUInt8(1, uint8(difficulty)); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE_BY_MAP_DIFF); stmt->setUInt16(0, uint16(mapid)); stmt->setUInt8(1, uint8(difficulty)); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); // calculate the next reset time uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME))/DAY) * DAY); if (period < DAY) period = DAY; uint32 next_reset = uint32(((resetTime + MINUTE) / DAY * DAY) + period + diff); SetResetTimeFor(mapid, difficulty, next_reset); ScheduleReset(true, time_t(next_reset-3600), InstResetEvent(1, mapid, difficulty, 0)); // Update it in the DB stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME); stmt->setUInt32(0, next_reset); stmt->setUInt16(1, uint16(mapid)); stmt->setUInt8(2, uint8(difficulty)); CharacterDatabase.Execute(stmt); } // note: this isn't fast but it's meant to be executed very rarely Map const* map = sMapMgr->CreateBaseMap(mapid); // _not_ include difficulty MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps(); MapInstanced::InstancedMaps::iterator mitr; uint32 timeLeft; for (mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr) { Map* map2 = mitr->second; if (!map2->IsDungeon()) continue; if (warn) { if (now <= resetTime) timeLeft = 0; else timeLeft = uint32(now - resetTime); ((InstanceMap*)map2)->SendResetWarnings(timeLeft); } else ((InstanceMap*)map2)->Reset(INSTANCE_RESET_GLOBAL); } /// @todo delete creature/gameobject respawn times even if the maps are not loaded }
void InstanceSaveManager::LoadResetTimes() { time_t now = time(NULL); time_t today = (now / DAY) * DAY; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::pair<uint32 /*PAIR32(map, difficulty)*/, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; // index instance ids by map/difficulty pairs for fast reset warning send typedef std::multimap<uint32 /*PAIR32(map, difficulty)*/, uint32 /*instanceid*/ > ResetTimeMapDiffInstances; ResetTimeMapDiffInstances mapDiffResetInstances; QueryResult result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC"); if (result) { do { Field* fields = result->Fetch(); uint32 instanceId = fields[0].GetUInt32(); // Instances are pulled in ascending order from db and nextInstanceId is initialized with 1, // so if the instance id is used, increment until we find the first unused one for a potential new instance if (sMapMgr->GetNextInstanceId() == instanceId) sMapMgr->SetNextInstanceId(instanceId + 1); // Mark instance id as being used sMapMgr->RegisterInstanceId(instanceId); if (time_t resettime = time_t(fields[3].GetUInt32())) { uint32 mapid = fields[1].GetUInt16(); uint32 difficulty = fields[2].GetUInt8(); instResetTime[instanceId] = ResetTimeMapDiffType(MAKE_PAIR32(mapid, difficulty), resettime); mapDiffResetInstances.insert(ResetTimeMapDiffInstances::value_type(MAKE_PAIR32(mapid, difficulty), instanceId)); } } while (result->NextRow()); // update reset time for normal instances with the max creature respawn time + X hours if (PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_GET_MAX_CREATURE_RESPAWNS))) { do { Field *fields = result->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt32() + 2 * HOUR); InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if (itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); } // schedule the reset times for (InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if (itr->second.second > now) ScheduleReset(true, itr->second.second, InstResetEvent(0, PAIR32_LOPART(itr->second.first), Difficulty(PAIR32_HIPART(itr->second.first)), itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if (result) { do { Field *fields = result->Fetch(); uint32 mapid = fields[0].GetUInt16(); Difficulty difficulty = Difficulty(fields[1].GetUInt32()); uint64 oldresettime = fields[2].GetUInt32(); MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty); if (!mapDiff) { sLog->outError("InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid, difficulty); continue; } // update the reset time if the hour in the configs changes uint64 newresettime = (oldresettime / DAY) * DAY + diff; if (oldresettime != newresettime) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u' AND difficulty = '%u'", uint32(newresettime), mapid, difficulty); SetResetTimeFor(mapid, difficulty, newresettime); } while (result->NextRow()); } ResetTimeMapDiffInstances::const_iterator in_itr; // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for (MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapid = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficulty const* mapDiff = &itr->second; if (!mapDiff->resetTime) continue; // the reset_delay must be at least one day uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME))/DAY) * DAY); if (period < DAY) period = DAY; time_t t = GetResetTimeFor(mapid, difficulty); if (!t) { // initialize the reset time t = today + period + diff; CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u', '%u', '%u')", mapid, difficulty, (uint32)t); } if (t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); } SetResetTimeFor(mapid, difficulty, t); // schedule the global reset/warning uint8 type; for (type = 1; type < 4; ++type) if (t - ResetTimeDelay[type-1] > now) break; ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, 0)); for (in_itr = mapDiffResetInstances.lower_bound(map_diff_pair); in_itr != mapDiffResetInstances.upper_bound(map_diff_pair); ++in_itr) ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, in_itr->second)); } }
void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) { ObjectGuid guid = _player->GetGUID(); std::string title; std::string description; uint8 type; uint8 repeatable; uint32 maxInvites; int32 dungeonId; uint32 eventPackedTime; uint32 unkPackedTime; uint32 flags; recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId; recvData.ReadPackedTime(eventPackedTime); recvData.ReadPackedTime(unkPackedTime); recvData >> flags; // prevent events in the past // To Do: properly handle timezones and remove the "- time_t(86400L)" hack if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L))) { recvData.rfinish(); return; } CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId, time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description); if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement()) if (Player* creator = ObjectAccessor::FindPlayer(guid)) calendarEvent->SetGuildId(creator->GetGuildId()); if (calendarEvent->IsGuildAnnouncement()) { // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite invite(0, calendarEvent->GetEventId(), ObjectGuid::Empty, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, ""); // WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind // of storage of the pointer as it will lead to memory corruption sCalendarMgr->AddInvite(calendarEvent, &invite); } else { // client limits the amount of players to be invited to 100 const uint32 MaxPlayerInvites = 100; uint32 inviteCount; ObjectGuid invitee[MaxPlayerInvites]; uint8 status[MaxPlayerInvites]; uint8 rank[MaxPlayerInvites]; memset(status, 0, sizeof(status)); memset(rank, 0, sizeof(rank)); try { recvData >> inviteCount; for (uint32 i = 0; i < inviteCount && i < MaxPlayerInvites; ++i) { recvData >> invitee[i].ReadAsPacked(); recvData >> status[i] >> rank[i]; } } catch (ByteBufferException const&) { delete calendarEvent; calendarEvent = NULL; throw; } SQLTransaction trans; if (inviteCount > 1) trans = CharacterDatabase.BeginTransaction(); for (uint32 i = 0; i < inviteCount && i < MaxPlayerInvites; ++i) { // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee[i], guid, 946684800, CalendarInviteStatus(status[i]), CalendarModerationRank(rank[i]), ""); sCalendarMgr->AddInvite(calendarEvent, invite, trans); } if (inviteCount > 1) CharacterDatabase.CommitTransaction(trans); } sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD); }
void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) { uint64 guid = _player->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_GET_CALENDAR [" UI64FMTD "]", guid); time_t cur_time = time_t(time(NULL)); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_SEND_CALENDAR [" UI64FMTD "]", guid); WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Impossible to get the correct size without doing a double iteration of some elements CalendarInviteIdList const& invites = sCalendarMgr->GetPlayerInvites(guid); data << uint32(invites.size()); for (CalendarInviteIdList::const_iterator it = invites.begin(); it != invites.end(); ++it) { CalendarInvite* invite = sCalendarMgr->GetInvite(*it); CalendarEvent* calendarEvent = invite ? sCalendarMgr->GetEvent(invite->GetEventId()) : NULL; if (calendarEvent) { data << uint64(invite->GetEventId()); data << uint64(invite->GetInviteId()); data << uint8(invite->GetStatus()); data << uint8(invite->GetRank()); data << uint8(calendarEvent->GetGuildId() != 0); data.appendPackGUID(calendarEvent->GetCreatorGUID()); } else { sLog->outError("SMSG_CALENDAR_SEND_CALENDAR: No Invite found with id [" UI64FMTD "]", *it); data << uint64(0) << uint64(0) << uint8(0) << uint8(0); data.appendPackGUID(0); } } CalendarEventIdList const& events = sCalendarMgr->GetPlayerEvents(guid); data << uint32(events.size()); for (CalendarEventIdList::const_iterator it = events.begin(); it != events.end(); ++it) { if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(*it)) { data << uint64(*it); data << calendarEvent->GetTitle().c_str(); data << uint32(calendarEvent->GetType()); data << uint32(calendarEvent->GetTime()); data << uint32(calendarEvent->GetFlags()); data << uint32(calendarEvent->GetDungeonId()); data.appendPackGUID(calendarEvent->GetCreatorGUID()); } else { sLog->outError("SMSG_CALENDAR_SEND_CALENDAR: No Event found with id [" UI64FMTD "]", *it); data << uint64(0) << uint8(0) << uint32(0) << uint32(0) << uint32(0) << uint32(0); data.appendPackGUID(0); } } data << uint32(cur_time); // server time data << uint32(secsToTimeBitFields(cur_time)); // server time uint32 counter = 0; size_t p_counter = data.wpos(); data << uint32(counter); // instance save count for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) for (Player::BoundInstancesMap::const_iterator itr = _player->_boundInstances[i].begin(); itr != _player->_boundInstances[i].end(); ++itr) if (itr->second.perm) { InstanceSave const* save = itr->second.save; data << uint32(save->GetMapId()); data << uint32(save->GetDifficulty()); data << uint32(save->GetResetTime() - cur_time); data << uint64(save->GetInstanceId()); // instance save id as unique instance copy id ++counter; } data.put<uint32>(p_counter, counter); data << uint32(1135753200); // unk (28.12.2005 07:00) counter = 0; p_counter = data.wpos(); data << uint32(counter); // raid reset count std::set<uint32> sentMaps; ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap(); for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr) { uint32 mapId = PAIR32_LOPART(itr->first); if (sentMaps.find(mapId) != sentMaps.end()) continue; MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); if (!mapEntry || !mapEntry->IsRaid()) continue; sentMaps.insert(mapId); data << uint32(mapId); data << uint32(itr->second - cur_time); data << uint32(mapEntry->unk_time); ++counter; } data.put<uint32>(p_counter, counter); // TODO: Fix this, how we do know how many and what holidays to send? uint32 holidayCount = 0; data << uint32(holidayCount); for (uint32 i = 0; i < holidayCount; ++i) { HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(666); data << uint32(holiday->Id); // m_ID data << uint32(holiday->Region); // m_region, might be looping data << uint32(holiday->Looping); // m_looping, might be region data << uint32(holiday->Priority); // m_priority data << uint32(holiday->CalendarFilterType); // m_calendarFilterType for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j) data << uint32(holiday->Date[j]); // 26 * m_date for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j) data << uint32(holiday->Duration[j]); // 10 * m_duration for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j) data << uint32(holiday->CalendarFlags[j]); // 10 * m_calendarFlags data << holiday->TextureFilename; // m_textureFilename (holiday name) } SendPacket(&data); }
void AuctionHouseMgr::LoadAuctions() { QueryResult* result = CharacterDatabase.Query("SELECT COUNT(*) FROM auction"); if (!result) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded 0 auctions. DB table `auction` is empty."); return; } Field* fields = result->Fetch(); uint32 AuctionCount = fields[0].GetUInt32(); delete result; if (!AuctionCount) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded 0 auctions. DB table `auction` is empty."); return; } result = CharacterDatabase.Query("SELECT id,houseid,itemguid,item_template,item_count,item_randompropertyid,itemowner,buyoutprice,time,moneyTime,buyguid,lastbid,startbid,deposit FROM auction"); if (!result) { BarGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded 0 auctions. DB table `auction` is empty."); return; } BarGoLink bar(AuctionCount); typedef std::map<uint32, std::wstring> PlayerNames; PlayerNames playerNames; // caching for load time do { fields = result->Fetch(); bar.step(); AuctionEntry* auction = new AuctionEntry; auction->Id = fields[0].GetUInt32(); uint32 houseid = fields[1].GetUInt32(); auction->itemGuidLow = fields[2].GetUInt32(); auction->itemTemplate = fields[3].GetUInt32(); auction->itemCount = fields[4].GetUInt32(); auction->itemRandomPropertyId = fields[5].GetUInt32(); auction->owner = fields[6].GetUInt32(); if (auction->owner) { std::wstring& plWName = playerNames[auction->owner]; if (plWName.empty()) { std::string plName; if (!sObjectMgr.GetPlayerNameByGUID(ObjectGuid(HIGHGUID_PLAYER, auction->owner), plName)) plName = sObjectMgr.GetMangosStringForDBCLocale(LANG_UNKNOWN); Utf8toWStr(plName, plWName); } auction->ownerName = plWName; } auction->buyout = fields[7].GetUInt64(); auction->expireTime = time_t(fields[8].GetUInt64()); auction->moneyDeliveryTime = time_t(fields[9].GetUInt64()); auction->bidder = fields[10].GetUInt32(); auction->bid = fields[11].GetUInt64(); auction->startbid = fields[12].GetUInt64(); auction->deposit = fields[13].GetUInt64(); auction->auctionHouseEntry = NULL; // init later if (auction->moneyDeliveryTime) auction->itemGuidLow = 0; // must be 0 if auction delivery pending else { // check if sold item exists for guid // and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems) Item* pItem = GetAItem(auction->itemGuidLow); if (!pItem) { auction->DeleteFromDB(); sLog.outError("Auction %u has not a existing item : %u, deleted", auction->Id, auction->itemGuidLow); delete auction; continue; } // overwrite by real item data if ((auction->itemTemplate != pItem->GetEntry()) || (auction->itemCount != pItem->GetCount()) || (auction->itemRandomPropertyId != pItem->GetItemRandomPropertyId())) { auction->itemTemplate = pItem->GetEntry(); auction->itemCount = pItem->GetCount(); auction->itemRandomPropertyId = pItem->GetItemRandomPropertyId(); // No SQL injection (no strings) CharacterDatabase.PExecute("UPDATE auction SET item_template = %u, item_count = %u, item_randompropertyid = %i WHERE itemguid = %u", auction->itemTemplate, auction->itemCount, auction->itemRandomPropertyId, auction->itemGuidLow); } } auction->auctionHouseEntry = sAuctionHouseStore.LookupEntry(houseid); if (!auction->auctionHouseEntry) { // need for send mail, use goblin auctionhouse auction->auctionHouseEntry = sAuctionHouseStore.LookupEntry(7); // Attempt send item back to owner std::ostringstream msgAuctionCanceledOwner; msgAuctionCanceledOwner << auction->itemTemplate << ":" << auction->itemRandomPropertyId << ":" << AUCTION_CANCELED << ":" << auction->Id << ":" << auction->itemCount; if (auction->itemGuidLow) { Item* pItem = GetAItem(auction->itemGuidLow); RemoveAItem(auction->itemGuidLow); auction->itemGuidLow = 0; // item will deleted or added to received mail list MailDraft(msgAuctionCanceledOwner.str(), "")// TODO: fix body .AddItem(pItem) .SendMailTo(MailReceiver(ObjectGuid(HIGHGUID_PLAYER, auction->owner)), auction, MAIL_CHECK_MASK_COPIED); } auction->DeleteFromDB(); delete auction; continue; } GetAuctionsMap(auction->auctionHouseEntry)->AddAuction(auction); } while (result->NextRow()); delete result; sLog.outString(); sLog.outString(">> Loaded %u auctions", AuctionCount); }
int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) { // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed, id, security; uint32 unk2; uint32 BuiltNumberClient; uint8 expansion = 0; uint8 xp_rate = 0; LocaleConstant locale; std::string account; Sha1Hash sha1; BigNumber v, s, g, N, K; WorldPacket packet, SendAddonPacked; // Read the content of the packet recvPacket >> BuiltNumberClient; recvPacket >> unk2; recvPacket >> account; recvPacket >> clientSeed; recvPacket.read(digest, 20); DEBUG_LOG("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u", BuiltNumberClient, unk2, account.c_str(), clientSeed); // Check the version of client trying to connect if (!IsAcceptableClientBuild(BuiltNumberClient)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_VERSION_MISMATCH); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (version mismatch)."); return -1; } // Get the account information from the realmd database std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below LoginDatabase.escape_string(safe_account); // No SQL injection, username escaped. QueryResult* result = LoginDatabase.PQuery("SELECT " "id, " //0 "gmlevel, " //1 "sessionkey, " //2 "last_ip, " //3 "locked, " //4 "v, " //5 "s, " //6 "expansion, " //7 "mutetime, " //8 "locale, " //9 "os " //10 "FROM account " "WHERE username = '******'", safe_account.c_str()); // Stop if the account is not found if (!result) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_UNKNOWN_ACCOUNT); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); return -1; } Field* fields = result->Fetch(); expansion = ((sWorld.getConfig(CONFIG_UINT32_EXPANSION) > fields[7].GetUInt8()) ? fields[7].GetUInt8() : sWorld.getConfig(CONFIG_UINT32_EXPANSION)); N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); v.SetHexStr(fields[5].GetString()); s.SetHexStr(fields[6].GetString()); const char* sStr = s.AsHexStr(); // Must be freed by OPENSSL_free() const char* vStr = v.AsHexStr(); // Must be freed by OPENSSL_free() DEBUG_LOG("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", sStr, vStr); OPENSSL_free((void*) sStr); OPENSSL_free((void*) vStr); ///- Re-check ip locking (same check as in realmd). if (fields[4].GetUInt8() == 1) // if ip is locked { if (strcmp(fields[3].GetString(), GetRemoteAddress().c_str())) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); delete result; BASIC_LOG("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); return -1; } } id = fields[0].GetUInt32(); security = fields[1].GetUInt16(); if (security > SEC_ADMINISTRATOR) // prevent invalid security settings in DB security = SEC_ADMINISTRATOR; K.SetHexStr(fields[2].GetString()); time_t mutetime = time_t (fields[8].GetUInt64()); locale = LocaleConstant(fields[9].GetUInt8()); if (locale >= MAX_LOCALE) locale = LOCALE_enUS; std::string os = fields[10].GetString(); delete result; // Re-check account ban (same check as in realmd) QueryResult* banresult = LoginDatabase.PQuery("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 AND (unbandate > UNIX_TIMESTAMP() OR unbandate = bandate)" "UNION " "SELECT 1 FROM ip_banned WHERE (unbandate = bandate OR unbandate > UNIX_TIMESTAMP()) AND ip = '%s'", id, GetRemoteAddress().c_str()); if (banresult) // if account banned { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_BANNED); SendPacket(packet); delete banresult; sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); return -1; } // Check for custom xp rate QueryResult* customXpResult = CharacterDatabase.PQuery ("SELECT xp_rate FROM account_xp_rates WHERE id = '%u'", id); if (customXpResult) { Field* xpFields = customXpResult->Fetch(); xp_rate = xpFields[0].GetUInt8(); } // Check locked state for server AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { WorldPacket Packet(SMSG_AUTH_RESPONSE, 1); Packet << uint8(AUTH_UNAVAILABLE); SendPacket(packet); BASIC_LOG("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); return -1; } // Check that Key and account name are the same on client and server Sha1Hash sha; uint32 t = 0; uint32 seed = m_Seed; sha.UpdateData(account); sha.UpdateData((uint8*) & t, 4); sha.UpdateData((uint8*) & clientSeed, 4); sha.UpdateData((uint8*) & seed, 4); sha.UpdateBigNumbers(&K, NULL); sha.Finalize(); if (memcmp(sha.GetDigest(), digest, 20)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); return -1; } std::string address = GetRemoteAddress(); DEBUG_LOG("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str(), address.c_str()); // Update the last_ip in the database // No SQL injection, username escaped. static SqlStatementID updAccount; SqlStatement stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET last_ip = ? WHERE username = ?"); stmt.PExecute(address.c_str(), account.c_str()); // NOTE ATM the socket is single-threaded, have this in mind ... ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, xp_rate, mutetime, locale), -1); m_Crypt.Init(&K); m_Session->LoadTutorialsData(); m_Session->InitWarden(&K, os); // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec ACE_OS::sleep(ACE_Time_Value(0, 10000)); sWorld.AddSession(m_Session); // Create and send the Addon packet if (sAddOnHandler.BuildAddonPacket(&recvPacket, &SendAddonPacked)) SendPacket(SendAddonPacked); return 0; }
void timespecAddMicro(struct timespec &ts, uint64_t micro) { ts.tv_sec += time_t(micro / 1000000); ts.tv_nsec += (micro % 1000000) * 1000L; timespecNormalize(ts); }