static bool HandleWpShowCommand(StringArguments args, CommandHandler handler) { if (args.Empty()) { return(false); } // first arg: on, off, first, last string show = args.NextString(); if (string.IsNullOrEmpty(show)) { return(false); } // second arg: GUID (optional, if a creature is selected) string guid_str = args.NextString(); uint pathid; Creature target = handler.GetSelectedCreature(); // Did player provide a PathID? if (string.IsNullOrEmpty(guid_str)) { // No PathID provided // . Player must have selected a creature if (!target) { handler.SendSysMessage(CypherStrings.SelectCreature); return(false); } pathid = target.GetWaypointPath(); } else { // PathID provided // Warn if player also selected a creature // . Creature selection is ignored <- if (target) { handler.SendSysMessage(CypherStrings.WaypointCreatselected); } if (!uint.TryParse(guid_str, out pathid)) { return(false); } } // Show info for the selected waypoint if (show == "info") { // Check if the user did specify a visual waypoint if (!target || target.GetEntry() != 1) { handler.SendSysMessage(CypherStrings.WaypointVpSelect); return(false); } PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_DATA_ALL_BY_WPGUID); stmt.AddValue(0, target.GetSpawnId()); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.WaypointNotfounddbproblem, target.GetSpawnId()); return(true); } handler.SendSysMessage("|cff00ffffDEBUG: wp show info:|r"); do { pathid = result.Read <uint>(0); uint point = result.Read <uint>(1); uint delay = result.Read <uint>(2); uint flag = result.Read <uint>(3); uint ev_id = result.Read <uint>(4); uint ev_chance = result.Read <uint>(5); handler.SendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff{0}|r|cff00ff00, Path ID: |r|cff00ffff{1}|r", point, pathid); handler.SendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff{0}|r", delay); handler.SendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff{0}|r", flag); handler.SendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff{0}|r", ev_id); handler.SendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff{0}|r", ev_chance); }while (result.NextRow()); return(true); } if (show == "on") { PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_DATA_POS_BY_ID); stmt.AddValue(0, pathid); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage("|cffff33ffPath no found.|r"); return(false); } handler.SendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff{0}|r", pathid); // Delete all visuals for this NPC stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_DATA_WPGUID_BY_ID); stmt.AddValue(0, pathid); SQLResult result2 = DB.World.Query(stmt); if (!result2.IsEmpty()) { bool hasError = false; do { ulong wpguid = result2.Read <ulong>(0); Creature creature = handler.GetCreatureFromPlayerMapByDbGuid(wpguid); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointNotremoved, wpguid); hasError = true; stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_CREATURE); stmt.AddValue(0, wpguid); DB.World.Execute(stmt); } else { creature.CombatStop(); creature.DeleteFromDB(); creature.AddObjectToRemoveList(); } }while (result2.NextRow()); if (hasError) { handler.SendSysMessage(CypherStrings.WaypointToofar1); handler.SendSysMessage(CypherStrings.WaypointToofar2); handler.SendSysMessage(CypherStrings.WaypointToofar3); } } do { uint point = result.Read <uint>(0); float x = result.Read <float>(1); float y = result.Read <float>(2); float z = result.Read <float>(3); uint id = 1; Player chr = handler.GetSession().GetPlayer(); Map map = chr.GetMap(); Position pos = new(x, y, z, chr.GetOrientation()); Creature creature = Creature.CreateCreature(id, map, pos); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, id); return(false); } PhasingHandler.InheritPhaseShift(creature, chr); creature.SaveToDB(map.GetId(), new List <Difficulty>() { map.GetDifficultyID() }); ulong dbGuid = creature.GetSpawnId(); // current "wpCreature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior creature.CleanupsBeforeDelete(); creature.Dispose(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); creature = Creature.CreateCreatureFromDB(dbGuid, map, true, true); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, id); return(false); } if (target) { creature.SetDisplayId(target.GetDisplayId()); creature.SetObjectScale(0.5f); creature.SetLevel(Math.Min(point, SharedConst.StrongMaxLevel)); } // Set "wpguid" column to the visual waypoint stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_WPGUID); stmt.AddValue(0, creature.GetSpawnId()); stmt.AddValue(1, pathid); stmt.AddValue(2, point); DB.World.Execute(stmt); }while (result.NextRow()); handler.SendSysMessage("|cff00ff00Showing the current creature's path.|r"); return(true); } if (show == "first") { handler.SendSysMessage("|cff00ff00DEBUG: wp first, pathid: {0}|r", pathid); PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_DATA_POS_FIRST_BY_ID); stmt.AddValue(0, pathid); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.WaypointNotfound, pathid); return(false); } float x = result.Read <float>(0); float y = result.Read <float>(1); float z = result.Read <float>(2); Player chr = handler.GetSession().GetPlayer(); Map map = chr.GetMap(); Position pos = new(x, y, z, chr.GetOrientation()); Creature creature = Creature.CreateCreature(1, map, pos); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); return(false); } PhasingHandler.InheritPhaseShift(creature, chr); creature.SaveToDB(map.GetId(), new List <Difficulty>() { map.GetDifficultyID() }); ulong dbGuid = creature.GetSpawnId(); // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior creature.CleanupsBeforeDelete(); creature.Dispose(); creature = Creature.CreateCreatureFromDB(dbGuid, map, true, true); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); return(false); } if (target) { creature.SetDisplayId(target.GetDisplayId()); creature.SetObjectScale(0.5f); } return(true); } if (show == "last") { handler.SendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff{0}|r", pathid); PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_DATA_POS_LAST_BY_ID); stmt.AddValue(0, pathid); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.WaypointNotfoundlast, pathid); return(false); } float x = result.Read <float>(0); float y = result.Read <float>(1); float z = result.Read <float>(2); float o = result.Read <float>(3); Player chr = handler.GetSession().GetPlayer(); Map map = chr.GetMap(); Position pos = new(x, y, z, o); Creature creature = Creature.CreateCreature(1, map, pos); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointNotcreated, 1); return(false); } PhasingHandler.InheritPhaseShift(creature, chr); creature.SaveToDB(map.GetId(), new List <Difficulty>() { map.GetDifficultyID() }); ulong dbGuid = creature.GetSpawnId(); // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior creature.CleanupsBeforeDelete(); creature.Dispose(); creature = Creature.CreateCreatureFromDB(dbGuid, map, true, true); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointNotcreated, 1); return(false); } if (target) { creature.SetDisplayId(target.GetDisplayId()); creature.SetObjectScale(0.5f); } return(true); } if (show == "off") { PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_CREATURE_BY_ID); stmt.AddValue(0, 1); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.WaypointVpNotfound); return(false); } bool hasError = false; do { ulong lowguid = result.Read <ulong>(0); Creature creature = handler.GetCreatureFromPlayerMapByDbGuid(lowguid); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointNotremoved, lowguid); hasError = true; stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_CREATURE); stmt.AddValue(0, lowguid); DB.World.Execute(stmt); } else { creature.CombatStop(); creature.DeleteFromDB(); creature.AddObjectToRemoveList(); } }while (result.NextRow()); // set "wpguid" column to "empty" - no visual waypoint spawned stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_ALL_WPGUID); DB.World.Execute(stmt); //DB.World.PExecute("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'"); if (hasError) { handler.SendSysMessage(CypherStrings.WaypointToofar1); handler.SendSysMessage(CypherStrings.WaypointToofar2); handler.SendSysMessage(CypherStrings.WaypointToofar3); } handler.SendSysMessage(CypherStrings.WaypointVpAllremoved); return(true); } handler.SendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r"); return(true); }
void _ResetOrWarnAll(uint mapid, Difficulty difficulty, bool warn, long resetTime) { // global reset for all instances of the given map MapRecord mapEntry = CliDB.MapStorage.LookupByKey(mapid); if (!mapEntry.Instanceable()) { return; } Log.outDebug(LogFilter.Misc, "InstanceSaveManager.ResetOrWarnAll: Processing map {0} ({1}) on difficulty {2} (warn? {3})", mapEntry.MapName[Global.WorldMgr.GetDefaultDbcLocale()], mapid, difficulty, warn); long now = Time.UnixTime; if (!warn) { // calculate the next reset time long next_reset = GetSubsequentResetTime(mapid, difficulty, resetTime); if (next_reset == 0) { return; } // delete them from the DB, even if not loaded SQLTransaction trans = new(); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_EXPIRED_CHAR_INSTANCE_BY_MAP_DIFF); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); trans.Append(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GROUP_INSTANCE_BY_MAP_DIFF); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); trans.Append(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_EXPIRED_INSTANCE_BY_MAP_DIFF); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); trans.Append(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_EXPIRE_CHAR_INSTANCE_BY_MAP_DIFF); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); trans.Append(stmt); DB.Characters.CommitTransaction(trans); // promote loaded binds to instances of the given map foreach (var pair in m_instanceSaveById.ToList()) { if (pair.Value.GetMapId() == mapid && pair.Value.GetDifficultyID() == difficulty) { _ResetSave(pair); } } SetResetTimeFor(mapid, difficulty, next_reset); ScheduleReset(true, next_reset - 3600, new InstResetEvent(1, mapid, difficulty, 0)); // Update it in the DB stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, (uint)next_reset); stmt.AddValue(1, (ushort)mapid); stmt.AddValue(2, (byte)difficulty); DB.Characters.Execute(stmt); } // note: this isn't fast but it's meant to be executed very rarely Map map = Global.MapMgr.CreateBaseMap(mapid); // _not_ include difficulty var instMaps = ((MapInstanced)map).GetInstancedMaps(); uint timeLeft; foreach (var pair in instMaps) { Map map2 = pair.Value; if (!map2.IsDungeon()) { continue; } if (warn) { if (now >= resetTime) { timeLeft = 0; } else { timeLeft = (uint)(resetTime - now); } ((InstanceMap)map2).SendResetWarnings(timeLeft); } else { ((InstanceMap)map2).Reset(InstanceResetMethod.Global); } } // @todo delete creature/gameobject respawn times even if the maps are not loaded }
public void SendMailTo(SQLTransaction trans, MailReceiver receiver, MailSender sender, MailCheckMask checkMask = MailCheckMask.None, uint deliver_delay = 0) { Player pReceiver = receiver.GetPlayer(); // can be NULL Player pSender = Global.ObjAccessor.FindPlayer(ObjectGuid.Create(HighGuid.Player, sender.GetSenderId())); if (pReceiver != null) { prepareItems(pReceiver, trans); // generate mail template items } uint mailId = Global.ObjectMgr.GenerateMailID(); long deliver_time = Time.UnixTime + deliver_delay; //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour uint expire_delay; // auction mail without any items and money if (sender.GetMailMessageType() == MailMessageType.Auction && m_items.Empty() && m_money == 0) { expire_delay = WorldConfig.GetUIntValue(WorldCfg.MailDeliveryDelay); } // default case: expire time if COD 3 days, if no COD 30 days (or 90 days if sender is a game master) else if (m_COD != 0) { expire_delay = 3 * Time.Day; } else { expire_delay = (uint)(pSender != null && pSender.IsGameMaster() ? 90 * Time.Day : 30 * Time.Day); } long expire_time = deliver_time + expire_delay; // Add to DB byte index = 0; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_MAIL); stmt.AddValue(index, mailId); stmt.AddValue(++index, (byte)sender.GetMailMessageType()); stmt.AddValue(++index, (sbyte)sender.GetStationery()); stmt.AddValue(++index, GetMailTemplateId()); stmt.AddValue(++index, sender.GetSenderId()); stmt.AddValue(++index, receiver.GetPlayerGUIDLow()); stmt.AddValue(++index, GetSubject()); stmt.AddValue(++index, GetBody()); stmt.AddValue(++index, !m_items.Empty()); stmt.AddValue(++index, expire_time); stmt.AddValue(++index, deliver_time); stmt.AddValue(++index, m_money); stmt.AddValue(++index, m_COD); stmt.AddValue(++index, (byte)checkMask); trans.Append(stmt); foreach (var item in m_items.Values) { stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_MAIL_ITEM); stmt.AddValue(0, mailId); stmt.AddValue(1, item.GetGUID().GetCounter()); stmt.AddValue(2, receiver.GetPlayerGUIDLow()); trans.Append(stmt); } // For online receiver update in game mail status and data if (pReceiver != null) { pReceiver.AddNewMailDeliverTime(deliver_time); if (pReceiver.IsMailsLoaded()) { Mail m = new Mail(); m.messageID = mailId; m.mailTemplateId = GetMailTemplateId(); m.subject = GetSubject(); m.body = GetBody(); m.money = GetMoney(); m.COD = GetCOD(); foreach (var item in m_items.Values) { m.AddItem(item.GetGUID().GetCounter(), item.GetEntry()); } m.messageType = sender.GetMailMessageType(); m.stationery = sender.GetStationery(); m.sender = sender.GetSenderId(); m.receiver = receiver.GetPlayerGUIDLow(); m.expire_time = expire_time; m.deliver_time = deliver_time; m.checkMask = checkMask; m.state = MailState.Unchanged; pReceiver.AddMail(m); // to insert new mail to beginning of maillist if (!m_items.Empty()) { foreach (var item in m_items.Values) { pReceiver.AddMItem(item); } } } else if (!m_items.Empty()) { deleteIncludedItems(null); } } else if (!m_items.Empty()) { deleteIncludedItems(null); } }
static bool HandleListItemCommand(StringArguments args, CommandHandler handler) { if (args.Empty()) { return(false); } string id = handler.extractKeyFromLink(args, "Hitem"); if (string.IsNullOrEmpty(id)) { return(false); } if (!uint.TryParse(id, out uint itemId) || itemId == 0) { handler.SendSysMessage(CypherStrings.CommandItemidinvalid, itemId); return(false); } ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(itemId); if (itemTemplate == null) { handler.SendSysMessage(CypherStrings.CommandItemidinvalid, itemId); return(false); } if (!uint.TryParse(args.NextString(), out uint count)) { count = 10; } if (count == 0) { return(false); } SQLResult result; // inventory case uint inventoryCount = 0; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHAR_INVENTORY_COUNT_ITEM); stmt.AddValue(0, itemId); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { inventoryCount = result.Read <uint>(0); } stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHAR_INVENTORY_ITEM_BY_ENTRY); stmt.AddValue(0, itemId); stmt.AddValue(1, count); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { do { ObjectGuid itemGuid = ObjectGuid.Create(HighGuid.Item, result.Read <ulong>(0)); uint itemBag = result.Read <uint>(1); byte itemSlot = result.Read <byte>(2); ObjectGuid ownerGuid = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(3)); uint ownerAccountId = result.Read <uint>(4); string ownerName = result.Read <string>(5); string itemPos; if (Player.IsEquipmentPos((byte)itemBag, itemSlot)) { itemPos = "[equipped]"; } else if (Player.IsInventoryPos((byte)itemBag, itemSlot)) { itemPos = "[in inventory]"; } else if (Player.IsBankPos((byte)itemBag, itemSlot)) { itemPos = "[in bank]"; } else { itemPos = ""; } handler.SendSysMessage(CypherStrings.ItemlistSlot, itemGuid.ToString(), ownerName, ownerGuid.ToString(), ownerAccountId, itemPos); }while (result.NextRow()); uint resultCount = (uint)result.GetRowCount(); if (count > resultCount) { count -= resultCount; } else if (count != 0) { count = 0; } } // mail case uint mailCount = 0; stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL_COUNT_ITEM); stmt.AddValue(0, itemId); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { mailCount = result.Read <uint>(0); } if (count > 0) { stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL_ITEMS_BY_ENTRY); stmt.AddValue(0, itemId); stmt.AddValue(1, count); result = DB.Characters.Query(stmt); } else { result = null; } if (result != null && !result.IsEmpty()) { do { ulong itemGuid = result.Read <ulong>(0); ulong itemSender = result.Read <ulong>(1); ulong itemReceiver = result.Read <ulong>(2); uint itemSenderAccountId = result.Read <uint>(3); string itemSenderName = result.Read <string>(4); uint itemReceiverAccount = result.Read <uint>(5); string itemReceiverName = result.Read <string>(6); string itemPos = "[in mail]"; handler.SendSysMessage(CypherStrings.ItemlistMail, itemGuid, itemSenderName, itemSender, itemSenderAccountId, itemReceiverName, itemReceiver, itemReceiverAccount, itemPos); }while (result.NextRow()); uint resultCount = (uint)result.GetRowCount(); if (count > resultCount) { count -= resultCount; } else if (count != 0) { count = 0; } } // auction case uint auctionCount = 0; stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_AUCTIONHOUSE_COUNT_ITEM); stmt.AddValue(0, itemId); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { auctionCount = result.Read <uint>(0); } if (count > 0) { stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_AUCTIONHOUSE_ITEM_BY_ENTRY); stmt.AddValue(0, itemId); stmt.AddValue(1, count); result = DB.Characters.Query(stmt); } else { result = null; } if (result != null && !result.IsEmpty()) { do { ObjectGuid itemGuid = ObjectGuid.Create(HighGuid.Item, result.Read <ulong>(0)); ObjectGuid owner = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(1)); uint ownerAccountId = result.Read <uint>(2); string ownerName = result.Read <string>(3); string itemPos = "[in auction]"; handler.SendSysMessage(CypherStrings.ItemlistAuction, itemGuid.ToString(), ownerName, owner.ToString(), ownerAccountId, itemPos); }while (result.NextRow()); } // guild bank case uint guildCount = 0; stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GUILD_BANK_COUNT_ITEM); stmt.AddValue(0, itemId); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { guildCount = result.Read <uint>(0); } stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GUILD_BANK_ITEM_BY_ENTRY); stmt.AddValue(0, itemId); stmt.AddValue(1, count); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { do { ObjectGuid itemGuid = ObjectGuid.Create(HighGuid.Item, result.Read <ulong>(0)); ObjectGuid guildGuid = ObjectGuid.Create(HighGuid.Guild, result.Read <ulong>(1)); string guildName = result.Read <string>(2); string itemPos = "[in guild bank]"; handler.SendSysMessage(CypherStrings.ItemlistGuild, itemGuid.ToString(), guildName, guildGuid.ToString(), itemPos); }while (result.NextRow()); uint resultCount = (uint)result.GetRowCount(); if (count > resultCount) { count -= resultCount; } else if (count != 0) { count = 0; } } if (inventoryCount + mailCount + auctionCount + guildCount == 0) { handler.SendSysMessage(CypherStrings.CommandNoitemfound); return(false); } handler.SendSysMessage(CypherStrings.CommandListitemmessage, itemId, inventoryCount + mailCount + auctionCount + guildCount, inventoryCount, mailCount, auctionCount, guildCount); return(true); }
public void SendAuctionWonMail(AuctionEntry auction, SQLTransaction trans) { Item item = GetAItem(auction.itemGUIDLow); if (!item) { return; } uint bidderAccId = 0; ObjectGuid bidderGuid = ObjectGuid.Create(HighGuid.Player, auction.bidder); Player bidder = Global.ObjAccessor.FindPlayer(bidderGuid); // data for gm.log string bidderName = ""; bool logGmTrade = false; if (bidder) { bidderAccId = bidder.GetSession().GetAccountId(); bidderName = bidder.GetName(); logGmTrade = bidder.GetSession().HasPermission(RBACPermissions.LogGmTrade); } else { bidderAccId = ObjectManager.GetPlayerAccountIdByGUID(bidderGuid); logGmTrade = Global.AccountMgr.HasPermission(bidderAccId, RBACPermissions.LogGmTrade, Global.WorldMgr.GetRealm().Id.Realm); if (logGmTrade && !ObjectManager.GetPlayerNameByGUID(bidderGuid, out bidderName)) { bidderName = Global.ObjectMgr.GetCypherString(CypherStrings.Unknown); } } if (logGmTrade) { ObjectGuid ownerGuid = ObjectGuid.Create(HighGuid.Player, auction.owner); string ownerName; if (!ObjectManager.GetPlayerNameByGUID(ownerGuid, out ownerName)) { ownerName = Global.ObjectMgr.GetCypherString(CypherStrings.Unknown); } uint ownerAccId = ObjectManager.GetPlayerAccountIdByGUID(ownerGuid); Log.outCommand(bidderAccId, $"GM {bidderName} (Account: {bidderAccId}) won item in auction: {item.GetTemplate().GetName()} (Entry: {item.GetEntry()} Count: {item.GetCount()}) and pay money: {auction.bid}. Original owner {ownerName} (Account: {ownerAccId})"); } // receiver exist if (bidder || bidderAccId != 0) { // set owner to bidder (to prevent delete item with sender char deleting) // owner in `data` will set at mail receive and item extracting PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ITEM_OWNER); stmt.AddValue(0, auction.bidder); stmt.AddValue(1, item.GetGUID().GetCounter()); trans.Append(stmt); if (bidder) { bidder.GetSession().SendAuctionWonNotification(auction, item); // FIXME: for offline player need also bidder.UpdateCriteria(CriteriaTypes.WonAuctions, 1); } new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Won), AuctionEntry.BuildAuctionMailBody(auction.owner, auction.bid, auction.buyout, 0, 0)) .AddItem(item) .SendMailTo(trans, new MailReceiver(bidder, auction.bidder), new MailSender(auction), MailCheckMask.Copied); } else { // bidder doesn't exist, delete the item Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow, true); } }
public void SaveToDB() { if (_criteriaProgress.Empty()) { return; } DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(_map.GetDifficultyID()); if (difficultyEntry == null || difficultyEntry.Flags.HasAnyFlag(DifficultyFlags.ChallengeMode)) // Map should have some sort of "CanSave" boolean that returns whether or not the map is savable. (Challenge modes cannot be saved for example) { return; } uint id = _map.GetInstanceId(); if (id == 0) { Log.outDebug(LogFilter.Scenario, "Scenario.SaveToDB: Can not save scenario progress without an instance save. Map.GetInstanceId() did not return an instance save."); return; } SQLTransaction trans = new(); foreach (var iter in _criteriaProgress) { if (!iter.Value.Changed) { continue; } Criteria criteria = Global.CriteriaMgr.GetCriteria(iter.Key); switch (criteria.Entry.Type) { // Blizzard only appears to store creature kills case CriteriaType.KillCreature: break; default: continue; } if (iter.Value.Counter != 0) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_SCENARIO_INSTANCE_CRITERIA); stmt.AddValue(0, id); stmt.AddValue(1, iter.Key); trans.Append(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_SCENARIO_INSTANCE_CRITERIA); stmt.AddValue(0, id); stmt.AddValue(1, iter.Key); stmt.AddValue(2, iter.Value.Counter); stmt.AddValue(3, iter.Value.Date); trans.Append(stmt); } iter.Value.Changed = false; } DB.Characters.CommitTransaction(trans); }
static bool HandleChannelSetOwnership(CommandHandler handler, StringArguments args) { if (args.Empty()) { return(false); } string channelStr = args.NextString(); string argStr = args.NextString(""); if (channelStr.IsEmpty() || argStr.IsEmpty()) { return(false); } uint channelId = 0; foreach (var channelEntry in CliDB.ChatChannelsStorage.Values) { if (channelEntry.Name[handler.GetSessionDbcLocale()].Equals(channelStr)) { channelId = channelEntry.Id; break; } } AreaTableRecord zoneEntry = null; foreach (var entry in CliDB.AreaTableStorage.Values) { if (entry.AreaName[handler.GetSessionDbcLocale()].Equals(channelStr)) { zoneEntry = entry; break; } } Player player = handler.GetSession().GetPlayer(); Channel channel = null; ChannelManager cMgr = ChannelManager.ForTeam(player.GetTeam()); if (cMgr != null) { channel = cMgr.GetChannel(channelId, channelStr, player, false, zoneEntry); } if (argStr.ToLower() == "on") { if (channel != null) { channel.SetOwnership(true); } PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_CHANNEL_OWNERSHIP); stmt.AddValue(0, 1); stmt.AddValue(1, channelStr); DB.Characters.Execute(stmt); handler.SendSysMessage(CypherStrings.ChannelEnableOwnership, channelStr); } else if (argStr.ToLower() == "off") { if (channel != null) { channel.SetOwnership(false); } PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_CHANNEL_OWNERSHIP); stmt.AddValue(0, 0); stmt.AddValue(1, channelStr); DB.Characters.Execute(stmt); handler.SendSysMessage(CypherStrings.ChannelDisableOwnership, channelStr); } else { return(false); } return(true); }
static bool HandleBanListCharacterCommand(StringArguments args, CommandHandler handler) { if (args.Empty()) { return(false); } string filter = args.NextString(); if (string.IsNullOrEmpty(filter)) { return(false); } PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GUID_BY_NAME_FILTER); stmt.AddValue(0, filter); SQLResult result = DB.Characters.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.BanlistNocharacter); return(true); } handler.SendSysMessage(CypherStrings.BanlistMatchingcharacter); // Chat short output if (handler.GetSession()) { do { PreparedStatement stmt2 = DB.Characters.GetPreparedStatement(CharStatements.SEL_BANNED_NAME); stmt2.AddValue(0, result.Read <ulong>(0)); SQLResult banResult = DB.Characters.Query(stmt2); if (!banResult.IsEmpty()) { handler.SendSysMessage(banResult.Read <string>(0)); } }while (result.NextRow()); } // Console wide output else { handler.SendSysMessage(CypherStrings.BanlistCharacters); handler.SendSysMessage(" =============================================================================== "); handler.SendSysMessage(CypherStrings.BanlistCharactersHeader); do { handler.SendSysMessage("-------------------------------------------------------------------------------"); string char_name = result.Read <string>(1); PreparedStatement stmt2 = DB.Characters.GetPreparedStatement(CharStatements.SEL_BANINFO_LIST); stmt2.AddValue(0, result.Read <ulong>(0)); SQLResult banInfo = DB.Characters.Query(stmt2); if (!banInfo.IsEmpty()) { do { long timeBan = banInfo.Read <uint>(0); DateTime tmBan = Time.UnixTimeToDateTime(timeBan); string bannedby = banInfo.Read <string>(2).Substring(0, 15); string banreason = banInfo.Read <string>(3).Substring(0, 15); if (banInfo.Read <uint>(0) == banInfo.Read <uint>(1)) { handler.SendSysMessage("|{0}|{1:D2}-{2:D2}-{3:D2} {4:D2}:{5:D2}| permanent |{6}|{7}|", char_name, tmBan.Year % 100, tmBan.Month + 1, tmBan.Day, tmBan.Hour, tmBan.Minute, bannedby, banreason); } else { long timeUnban = banInfo.Read <uint>(1); DateTime tmUnban = Time.UnixTimeToDateTime(timeUnban); handler.SendSysMessage("|{0}|{1:D2}-{2:D2}-{3:D2} {4:D2}:{5:D2}|{6:D2}-{7:D2}-{8:D2} {9:D2}:{10:D2}|{11}|{12}|", char_name, tmBan.Year % 100, tmBan.Month + 1, tmBan.Day, tmBan.Hour, tmBan.Minute, tmUnban.Year % 100, tmUnban.Month + 1, tmUnban.Day, tmUnban.Hour, tmUnban.Minute, bannedby, banreason); } }while (banInfo.NextRow()); } }while (result.NextRow()); handler.SendSysMessage(" =============================================================================== "); } return(true); }
static bool HandleBanListIPCommand(StringArguments args, CommandHandler handler) { PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.DelExpiredIpBans); DB.Login.Execute(stmt); string filterStr = args.NextString(); string filter = !string.IsNullOrEmpty(filterStr) ? filterStr : ""; SQLResult result; if (string.IsNullOrEmpty(filter)) { stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_IP_BANNED_ALL); result = DB.Login.Query(stmt); } else { stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_IP_BANNED_BY_IP); stmt.AddValue(0, filter); result = DB.Login.Query(stmt); } if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.BanlistNoip); return(true); } handler.SendSysMessage(CypherStrings.BanlistMatchingip); // Chat short output if (handler.GetSession()) { do { handler.SendSysMessage("{0}", result.Read <string>(0)); }while (result.NextRow()); } // Console wide output else { handler.SendSysMessage(CypherStrings.BanlistIps); handler.SendSysMessage(" ==============================================================================="); handler.SendSysMessage(CypherStrings.BanlistIpsHeader); do { handler.SendSysMessage("-------------------------------------------------------------------------------"); long timeBan = result.Read <uint>(1); DateTime tmBan = Time.UnixTimeToDateTime(timeBan); string bannedby = result.Read <string>(3).Substring(0, 15); string banreason = result.Read <string>(4).Substring(0, 15); if (result.Read <uint>(1) == result.Read <uint>(2)) { handler.SendSysMessage("|{0}|{1:D2}-{2:D2}-{3:D2} {4:D2}:{5:D2}| permanent |{6}|{7}|", result.Read <string>(0), tmBan.Year % 100, tmBan.Month + 1, tmBan.Day, tmBan.Hour, tmBan.Minute, bannedby, banreason); } else { long timeUnban = result.Read <uint>(2); DateTime tmUnban; tmUnban = Time.UnixTimeToDateTime(timeUnban); handler.SendSysMessage("|{0}|{1:D2}-{2:D2}-{3:D2} {4:D2}:{5:D2}|{6:D2}-{7:D2}-{8:D2} {9:D2}:{10:D2}|{11}|{12}|", result.Read <string>(0), tmBan.Year % 100, tmBan.Month + 1, tmBan.Day, tmBan.Hour, tmBan.Minute, tmUnban.Year % 100, tmUnban.Month + 1, tmUnban.Day, tmUnban.Hour, tmUnban.Minute, bannedby, banreason); } }while (result.NextRow()); handler.SendSysMessage(" ==============================================================================="); } return(true); }
static bool HandleCharacterRenameCommand(StringArguments args, CommandHandler handler) { Player target; ObjectGuid targetGuid; string targetName; if (!handler.extractPlayerTarget(args, out target, out targetGuid, out targetName)) { return(false); } string newNameStr = args.NextString(); if (!string.IsNullOrEmpty(newNameStr)) { string playerOldName; string newName = newNameStr; if (target) { // check online security if (handler.HasLowerSecurity(target, ObjectGuid.Empty)) { return(false); } playerOldName = target.GetName(); } else { // check offline security if (handler.HasLowerSecurity(null, targetGuid)) { return(false); } ObjectManager.GetPlayerNameByGUID(targetGuid, out playerOldName); } if (!ObjectManager.NormalizePlayerName(ref newName)) { handler.SendSysMessage(CypherStrings.BadValue); return(false); } if (ObjectManager.CheckPlayerName(newName, target ? target.GetSession().GetSessionDbcLocale() : Global.WorldMgr.GetDefaultDbcLocale(), true) != ResponseCodes.CharNameSuccess) { handler.SendSysMessage(CypherStrings.BadValue); return(false); } WorldSession session = handler.GetSession(); if (session != null) { if (!session.HasPermission(RBACPermissions.SkipCheckCharacterCreationReservedname) && Global.ObjectMgr.IsReservedName(newName)) { handler.SendSysMessage(CypherStrings.ReservedName); return(false); } } PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHECK_NAME); stmt.AddValue(0, newName); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { handler.SendSysMessage(CypherStrings.RenamePlayerAlreadyExists, newName); return(false); } // Remove declined name from db stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CHAR_DECLINED_NAME); stmt.AddValue(0, targetGuid.GetCounter()); DB.Characters.Execute(stmt); if (target) { target.SetName(newName); session = target.GetSession(); if (session != null) { session.KickPlayer(); } } else { stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_NAME_BY_GUID); stmt.AddValue(0, newName); stmt.AddValue(1, targetGuid.GetCounter()); DB.Characters.Execute(stmt); } Global.WorldMgr.UpdateCharacterInfo(targetGuid, newName); handler.SendSysMessage(CypherStrings.RenamePlayerWithNewName, playerOldName, newName); Player player = handler.GetPlayer(); if (player) { Log.outCommand(session.GetAccountId(), "GM {0} (Account: {1}) forced rename {2} to player {3} (Account: {4})", player.GetName(), session.GetAccountId(), newName, playerOldName, ObjectManager.GetPlayerAccountIdByGUID(targetGuid)); } else { Log.outCommand(0, "CONSOLE forced rename '{0}' to '{1}' ({2})", playerOldName, newName, targetGuid.ToString()); } } else { if (target) { // check online security if (handler.HasLowerSecurity(target, ObjectGuid.Empty)) { return(false); } handler.SendSysMessage(CypherStrings.RenamePlayer, handler.GetNameLink(target)); target.SetAtLoginFlag(AtLoginFlags.Rename); } else { // check offline security if (handler.HasLowerSecurity(null, targetGuid)) { return(false); } string oldNameLink = handler.playerLink(targetName); handler.SendSysMessage(CypherStrings.RenamePlayerGuid, oldNameLink, targetGuid.ToString()); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ADD_AT_LOGIN_FLAG); stmt.AddValue(0, AtLoginFlags.Rename); stmt.AddValue(1, targetGuid.GetCounter()); DB.Characters.Execute(stmt); } } return(true); }
public void SaveToDB(SQLTransaction trans) { DeleteFromDB(_owner.GetGUID().GetCounter(), trans); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_GARRISON); stmt.AddValue(0, _owner.GetGUID().GetCounter()); stmt.AddValue(1, _siteLevel.Id); stmt.AddValue(2, _followerActivationsRemainingToday); trans.Append(stmt); foreach (uint building in _knownBuildings) { stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_GARRISON_BLUEPRINTS); stmt.AddValue(0, _owner.GetGUID().GetCounter()); stmt.AddValue(1, building); trans.Append(stmt); } foreach (var plot in _plots.Values) { if (plot.BuildingInfo.PacketInfo.HasValue) { stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_GARRISON_BUILDINGS); stmt.AddValue(0, _owner.GetGUID().GetCounter()); stmt.AddValue(1, plot.BuildingInfo.PacketInfo.Value.GarrPlotInstanceID); stmt.AddValue(2, plot.BuildingInfo.PacketInfo.Value.GarrBuildingID); stmt.AddValue(3, plot.BuildingInfo.PacketInfo.Value.TimeBuilt); stmt.AddValue(4, plot.BuildingInfo.PacketInfo.Value.Active); trans.Append(stmt); } } foreach (var follower in _followers.Values) { byte index = 0; stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_GARRISON_FOLLOWERS); stmt.AddValue(index++, follower.PacketInfo.DbID); stmt.AddValue(index++, _owner.GetGUID().GetCounter()); stmt.AddValue(index++, follower.PacketInfo.GarrFollowerID); stmt.AddValue(index++, follower.PacketInfo.Quality); stmt.AddValue(index++, follower.PacketInfo.FollowerLevel); stmt.AddValue(index++, follower.PacketInfo.ItemLevelWeapon); stmt.AddValue(index++, follower.PacketInfo.ItemLevelArmor); stmt.AddValue(index++, follower.PacketInfo.Xp); stmt.AddValue(index++, follower.PacketInfo.CurrentBuildingID); stmt.AddValue(index++, follower.PacketInfo.CurrentMissionID); stmt.AddValue(index++, follower.PacketInfo.FollowerStatus); trans.Append(stmt); byte slot = 0; foreach (GarrAbilityRecord ability in follower.PacketInfo.AbilityID) { stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_GARRISON_FOLLOWER_ABILITIES); stmt.AddValue(0, follower.PacketInfo.DbID); stmt.AddValue(1, ability.Id); stmt.AddValue(2, slot++); trans.Append(stmt); } } }
static bool HandleCharacterChangeAccountCommand(StringArguments args, CommandHandler handler) { string playerNameStr; string accountName; handler.ExtractOptFirstArg(args, out playerNameStr, out accountName); if (accountName.IsEmpty()) { return(false); } ObjectGuid targetGuid; string targetName; if (!handler.ExtractPlayerTarget(new StringArguments(playerNameStr), out _, out targetGuid, out targetName)) { return(false); } CharacterCacheEntry characterInfo = Global.CharacterCacheStorage.GetCharacterCacheByGuid(targetGuid); if (characterInfo == null) { handler.SendSysMessage(CypherStrings.PlayerNotFound); return(false); } uint oldAccountId = characterInfo.AccountId; uint newAccountId = oldAccountId; PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_ID_BY_NAME); stmt.AddValue(0, accountName); SQLResult result = DB.Login.Query(stmt); if (!result.IsEmpty()) { newAccountId = result.Read <uint>(0); } else { handler.SendSysMessage(CypherStrings.AccountNotExist, accountName); return(false); } // nothing to do :) if (newAccountId == oldAccountId) { return(true); } uint charCount = Global.AccountMgr.GetCharactersCount(newAccountId); if (charCount != 0) { if (charCount >= WorldConfig.GetIntValue(WorldCfg.CharactersPerRealm)) { handler.SendSysMessage(CypherStrings.AccountCharacterListFull, accountName, newAccountId); return(false); } } stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ACCOUNT_BY_GUID); stmt.AddValue(0, newAccountId); stmt.AddValue(1, targetGuid.GetCounter()); DB.Characters.DirectExecute(stmt); Global.WorldMgr.UpdateRealmCharCount(oldAccountId); Global.WorldMgr.UpdateRealmCharCount(newAccountId); Global.CharacterCacheStorage.UpdateCharacterAccountId(targetGuid, newAccountId); handler.SendSysMessage(CypherStrings.ChangeAccountSuccess, targetName, accountName); string logString = $"changed ownership of player {targetName} ({targetGuid.ToString()}) from account {oldAccountId} to account {newAccountId}"; WorldSession session = handler.GetSession(); if (session != null) { Player player = session.GetPlayer(); if (player != null) { Log.outCommand(session.GetAccountId(), $"GM {player.GetName()} (Account: {session.GetAccountId()}) {logString}"); } } else { Log.outCommand(0, $"{handler.GetCypherString(CypherStrings.Console)} {logString}"); } return(true); }
public void SaveToDB() { // prevent DB data inconsistence problems and duplicates SQLTransaction trans = new SQLTransaction(); DeleteFromDB(trans); StringBuilder items = new StringBuilder(); for (var i = 0; i < EquipmentSlot.End; ++i) { items.Append($"{m_corpseData.Items[i]} "); } byte index = 0; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CORPSE); stmt.AddValue(index++, GetOwnerGUID().GetCounter()); // guid stmt.AddValue(index++, GetPositionX()); // posX stmt.AddValue(index++, GetPositionY()); // posY stmt.AddValue(index++, GetPositionZ()); // posZ stmt.AddValue(index++, GetOrientation()); // orientation stmt.AddValue(index++, GetMapId()); // mapId stmt.AddValue(index++, (uint)m_corpseData.DisplayID); // displayId stmt.AddValue(index++, items.ToString()); // itemCache stmt.AddValue(index++, (byte)m_corpseData.RaceID); // race stmt.AddValue(index++, (byte)m_corpseData.Class); // class stmt.AddValue(index++, (byte)m_corpseData.Sex); // gender stmt.AddValue(index++, (uint)m_corpseData.Flags); // flags stmt.AddValue(index++, (uint)m_corpseData.DynamicFlags); // dynFlags stmt.AddValue(index++, (uint)m_time); // time stmt.AddValue(index++, (uint)GetCorpseType()); // corpseType stmt.AddValue(index++, GetInstanceId()); // instanceId trans.Append(stmt); foreach (var phaseId in GetPhaseShift().GetPhases().Keys) { index = 0; stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CORPSE_PHASES); stmt.AddValue(index++, GetOwnerGUID().GetCounter()); // OwnerGuid stmt.AddValue(index++, phaseId); // PhaseId trans.Append(stmt); } foreach (var customization in m_corpseData.Customizations) { index = 0; stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CORPSE_CUSTOMIZATIONS); stmt.AddValue(index++, GetOwnerGUID().GetCounter()); // OwnerGuid stmt.AddValue(index++, customization.ChrCustomizationOptionID); stmt.AddValue(index++, customization.ChrCustomizationChoiceID); trans.Append(stmt); } DB.Characters.CommitTransaction(trans); }
void HandleAuthSessionCallback(AuthSession authSession, SQLResult result) { // Stop if the account is not found if (result.IsEmpty()) { Log.outError(LogFilter.Network, "HandleAuthSession: Sent Auth Response (unknown account)."); CloseSocket(); return; } AccountInfo account = new AccountInfo(result.GetFields()); // For hook purposes, we get Remoteaddress at this point. string address = GetRemoteIpAddress().ToString(); byte[] clientSeed = ClientTypeSeed_Win; if (account.game.OS == "Wn64") { clientSeed = ClientTypeSeed_Wn64; } else if (account.game.OS == "Mc64") { clientSeed = ClientTypeSeed_Mc64; } Sha256 digestKeyHash = new Sha256(); digestKeyHash.Process(account.game.SessionKey, account.game.SessionKey.Length); digestKeyHash.Finish(clientSeed, clientSeed.Length); HmacSha256 hmac = new HmacSha256(digestKeyHash.Digest); hmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Count); hmac.Process(_serverChallenge, 16); hmac.Finish(AuthCheckSeed, 16); // Check that Key and account name are the same on client and server if (!hmac.Digest.Compare(authSession.Digest)) { Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Authentication failed for account: {0} ('{1}') address: {2}", account.game.Id, authSession.RealmJoinTicket, address); CloseSocket(); return; } Sha256 keyData = new Sha256(); keyData.Finish(account.game.SessionKey, account.game.SessionKey.Length); HmacSha256 sessionKeyHmac = new HmacSha256(keyData.Digest); sessionKeyHmac.Process(_serverChallenge, 16); sessionKeyHmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Count); sessionKeyHmac.Finish(SessionKeySeed, 16); _sessionKey = new byte[40]; var sessionKeyGenerator = new SessionKeyGenerator(sessionKeyHmac.Digest, 32); sessionKeyGenerator.Generate(_sessionKey, 40); // As we don't know if attempted login process by ip works, we update last_attempt_ip right away PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_LAST_ATTEMPT_IP); stmt.AddValue(0, address); stmt.AddValue(1, authSession.RealmJoinTicket); DB.Login.Execute(stmt); // This also allows to check for possible "hack" attempts on account stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_ACCOUNT_INFO_CONTINUED_SESSION); stmt.AddValue(0, _sessionKey.ToHexString()); stmt.AddValue(1, account.game.Id); DB.Login.Execute(stmt); // First reject the connection if packet contains invalid data or realm state doesn't allow logging in if (Global.WorldMgr.IsClosed()) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: World closed, denying client ({0}).", GetRemoteIpAddress()); CloseSocket(); return; } if (authSession.RealmID != Global.WorldMgr.GetRealm().Id.Realm) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Client {0} requested connecting with realm id {1} but this realm has id {2} set in config.", GetRemoteIpAddress().ToString(), authSession.RealmID, Global.WorldMgr.GetRealm().Id.Realm); CloseSocket(); return; } // Must be done before WorldSession is created bool wardenActive = WorldConfig.GetBoolValue(WorldCfg.WardenEnabled); if (wardenActive && account.game.OS != "Win" && account.game.OS != "Wn64" && account.game.OS != "Mc64") { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Client {0} attempted to log in using invalid client OS ({1}).", address, account.game.OS); CloseSocket(); return; } //Re-check ip locking (same check as in auth). if (account.battleNet.IsLockedToIP) // if ip is locked { if (account.battleNet.LastIP != address) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outDebug(LogFilter.Network, "HandleAuthSession: Sent Auth Response (Account IP differs)."); CloseSocket(); return; } } else if (!account.battleNet.LockCountry.IsEmpty() && account.battleNet.LockCountry != "00" && !_ipCountry.IsEmpty()) { if (account.battleNet.LockCountry != _ipCountry) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outDebug(LogFilter.Network, "WorldSocket.HandleAuthSession: Sent Auth Response (Account country differs. Original country: {0}, new country: {1}).", account.battleNet.LockCountry, _ipCountry); CloseSocket(); return; } } long mutetime = account.game.MuteTime; //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { mutetime = Time.UnixTime + mutetime; stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_MUTE_TIME_LOGIN); stmt.AddValue(0, mutetime); stmt.AddValue(1, account.game.Id); DB.Login.Execute(stmt); } if (account.IsBanned()) // if account banned { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outError(LogFilter.Network, "WorldSocket:HandleAuthSession: Sent Auth Response (Account banned)."); CloseSocket(); return; } // Check locked state for server AccountTypes allowedAccountType = Global.WorldMgr.GetPlayerSecurityLimit(); if (allowedAccountType > AccountTypes.Player && account.game.Security < allowedAccountType) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outInfo(LogFilter.Network, "WorldSocket:HandleAuthSession: User tries to login but his security level is not enough"); CloseSocket(); return; } Log.outDebug(LogFilter.Network, "WorldSocket:HandleAuthSession: Client '{0}' authenticated successfully from {1}.", authSession.RealmJoinTicket, address); // Update the last_ip in the database stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_LAST_IP); stmt.AddValue(0, address); stmt.AddValue(1, authSession.RealmJoinTicket); DB.Login.Execute(stmt); _worldSession = new WorldSession(account.game.Id, authSession.RealmJoinTicket, account.battleNet.Id, this, account.game.Security, (Expansion)account.game.Expansion, mutetime, account.game.OS, account.battleNet.Locale, account.game.Recruiter, account.game.IsRectuiter); // Initialize Warden system only if it is enabled by config //if (wardenActive) //_worldSession.InitWarden(_sessionKey); _queryProcessor.AddQuery(_worldSession.LoadPermissionsAsync().WithCallback(LoadSessionPermissionsCallback)); }
public void ActivateTalentGroup(ChrSpecializationRecord spec) { if (GetActiveTalentGroup() == spec.OrderIndex) { return; } if (IsNonMeleeSpellCast(false)) { InterruptNonMeleeSpells(false); } SQLTransaction trans = new SQLTransaction(); _SaveActions(trans); DB.Characters.CommitTransaction(trans); // TO-DO: We need more research to know what happens with warlock's reagent Pet pet = GetPet(); if (pet) { RemovePet(pet, PetSaveMode.NotInSlot); } ClearAllReactives(); UnsummonAllTotems(); ExitVehicle(); RemoveAllControlled(); // remove single target auras at other targets var scAuras = GetSingleCastAuras(); foreach (var aura in scAuras) { if (aura.GetUnitOwner() != this) { aura.Remove(); } } // Let client clear his current Actions SendActionButtons(2); foreach (var talentInfo in CliDB.TalentStorage.Values) { // unlearn only talents for character class // some spell learned by one class as normal spells or know at creation but another class learn it as talent, // to prevent unexpected lost normal learned spell skip another class talents if (talentInfo.ClassID != (int)GetClass()) { continue; } if (talentInfo.SpellID == 0) { continue; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None); if (spellInfo == null) { continue; } RemoveSpell(talentInfo.SpellID, true); // search for spells that the talent teaches and unlearn them foreach (SpellEffectInfo effect in spellInfo.GetEffects()) { if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell) { RemoveSpell(effect.TriggerSpell, true); } } if (talentInfo.OverridesSpellID != 0) { RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID); } } foreach (var talentInfo in CliDB.PvpTalentStorage.Values) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None); if (spellInfo == null) { continue; } RemoveSpell(talentInfo.SpellID, true); // search for spells that the talent teaches and unlearn them foreach (SpellEffectInfo effect in spellInfo.GetEffects()) { if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell) { RemoveSpell(effect.TriggerSpell, true); } } if (talentInfo.OverridesSpellID != 0) { RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID); } } // Remove spec specific spells RemoveSpecializationSpells(); foreach (uint glyphId in GetGlyphs(GetActiveTalentGroup())) { RemoveAurasDueToSpell(CliDB.GlyphPropertiesStorage.LookupByKey(glyphId).SpellID); } SetActiveTalentGroup(spec.OrderIndex); SetPrimarySpecialization(spec.Id); foreach (var talentInfo in CliDB.TalentStorage.Values) { // learn only talents for character class if (talentInfo.ClassID != (int)GetClass()) { continue; } if (talentInfo.SpellID == 0) { continue; } if (HasTalent(talentInfo.Id, GetActiveTalentGroup())) { LearnSpell(talentInfo.SpellID, false); // add the talent to the PlayerSpellMap if (talentInfo.OverridesSpellID != 0) { AddOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID); } } } for (byte slot = 0; slot < PlayerConst.MaxPvpTalentSlots; ++slot) { PvpTalentRecord talentInfo = CliDB.PvpTalentStorage.LookupByKey(GetPvpTalentMap(GetActiveTalentGroup())[slot]); if (talentInfo == null) { continue; } if (talentInfo.SpellID == 0) { continue; } AddPvpTalent(talentInfo, GetActiveTalentGroup(), slot); } LearnSpecializationSpells(); if (CanUseMastery()) { for (uint i = 0; i < PlayerConst.MaxMasterySpells; ++i) { uint mastery = spec.MasterySpellID[i]; if (mastery != 0) { LearnSpell(mastery, false); } } } InitTalentForLevel(); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_ACTIONS_SPEC); stmt.AddValue(0, GetGUID().GetCounter()); stmt.AddValue(1, GetActiveTalentGroup()); WorldSession mySess = GetSession(); mySess.GetQueryProcessor().AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(result => { // in case player logs out before db response (player would be deleted in that case) Player thisPlayer = mySess.GetPlayer(); if (thisPlayer != null) { thisPlayer.LoadActions(result); } })); UpdateDisplayPower(); PowerType pw = GetPowerType(); if (pw != PowerType.Mana) { SetPower(PowerType.Mana, 0); // Mana must be 0 even if it isn't the active power type. } SetPower(pw, 0); UpdateItemSetAuras(false); // update visible transmog for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) { Item equippedItem = GetItemByPos(InventorySlots.Bag0, i); if (equippedItem) { SetVisibleItemSlot(i, equippedItem); } } foreach (uint glyphId in GetGlyphs(spec.OrderIndex)) { CastSpell(this, CliDB.GlyphPropertiesStorage.LookupByKey(glyphId).SpellID, true); } ActiveGlyphs activeGlyphs = new ActiveGlyphs(); foreach (uint glyphId in GetGlyphs(spec.OrderIndex)) { List <uint> bindableSpells = Global.DB2Mgr.GetGlyphBindableSpells(glyphId); foreach (uint bindableSpell in bindableSpells) { if (HasSpell(bindableSpell) && !m_overrideSpells.ContainsKey(bindableSpell)) { activeGlyphs.Glyphs.Add(new GlyphBinding(bindableSpell, (ushort)glyphId)); } } } activeGlyphs.IsFullUpdate = true; SendPacket(activeGlyphs); Item item = GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth, ItemSearchLocation.Everywhere); if (item != null) { AzeriteItem azeriteItem = item.ToAzeriteItem(); if (azeriteItem != null) { if (azeriteItem.IsEquipped()) { ApplyAllAzeriteEmpoweredItemMods(false); ApplyAzeritePowers(azeriteItem, false); } azeriteItem.SetSelectedAzeriteEssences(spec.Id); if (azeriteItem.IsEquipped()) { ApplyAzeritePowers(azeriteItem, true); ApplyAllAzeriteEmpoweredItemMods(true); } azeriteItem.SetState(ItemUpdateState.Changed, this); } } var shapeshiftAuras = GetAuraEffectsByType(AuraType.ModShapeshift); foreach (AuraEffect aurEff in shapeshiftAuras) { aurEff.HandleShapeshiftBoosts(this, false); aurEff.HandleShapeshiftBoosts(this, true); } }
public void LoadAzeriteItemData(Player owner, AzeriteData azeriteData) { bool needSave = false; if (!CliDB.AzeriteLevelInfoStorage.ContainsKey(azeriteData.Level)) { azeriteData.Xp = 0; azeriteData.Level = 1; azeriteData.KnowledgeLevel = GetCurrentKnowledgeLevel(); needSave = true; } else if (azeriteData.Level > PlayerConst.MaxAzeriteItemLevel) { azeriteData.Xp = 0; azeriteData.Level = PlayerConst.MaxAzeriteItemLevel; needSave = true; } if (azeriteData.KnowledgeLevel != GetCurrentKnowledgeLevel()) { // rescale XP to maintain same progress % ulong oldMax = CalcTotalXPToNextLevel(azeriteData.Level, azeriteData.KnowledgeLevel); azeriteData.KnowledgeLevel = GetCurrentKnowledgeLevel(); ulong newMax = CalcTotalXPToNextLevel(azeriteData.Level, azeriteData.KnowledgeLevel); azeriteData.Xp = (ulong)(azeriteData.Xp / (double)oldMax * newMax); needSave = true; } else if (azeriteData.KnowledgeLevel > PlayerConst.MaxAzeriteItemKnowledgeLevel) { azeriteData.KnowledgeLevel = PlayerConst.MaxAzeriteItemKnowledgeLevel; needSave = true; } SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.Xp), azeriteData.Xp); SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.Level), azeriteData.Level); SetUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.KnowledgeLevel), azeriteData.KnowledgeLevel); foreach (uint azeriteItemMilestonePowerId in azeriteData.AzeriteItemMilestonePowers) { AddUnlockedEssenceMilestone(azeriteItemMilestonePowerId); } UnlockDefaultMilestones(); foreach (AzeriteEssencePowerRecord unlockedAzeriteEssence in azeriteData.UnlockedAzeriteEssences) { SetEssenceRank((uint)unlockedAzeriteEssence.AzeriteEssenceID, unlockedAzeriteEssence.Tier); } foreach (AzeriteItemSelectedEssencesData selectedEssenceData in azeriteData.SelectedAzeriteEssences) { if (selectedEssenceData.SpecializationId == 0) { continue; } var selectedEssences = new SelectedAzeriteEssences(); selectedEssences.ModifyValue(selectedEssences.SpecializationID).SetValue(selectedEssenceData.SpecializationId); for (int i = 0; i < SharedConst.MaxAzeriteEssenceSlot; ++i) { // Check if essence was unlocked if (GetEssenceRank(selectedEssenceData.AzeriteEssenceId[i]) == 0) { continue; } selectedEssences.ModifyValue(selectedEssences.AzeriteEssenceID, i) = selectedEssenceData.AzeriteEssenceId[i]; } if (owner != null && owner.GetPrimarySpecialization() == selectedEssenceData.SpecializationId) { selectedEssences.ModifyValue(selectedEssences.Enabled).SetValue(1); } AddDynamicUpdateFieldValue(m_values.ModifyValue(m_azeriteItemData).ModifyValue(m_azeriteItemData.SelectedEssences), selectedEssences); } // add selected essences for current spec if (owner != null && GetSelectedAzeriteEssences() == null) { CreateSelectedAzeriteEssences(owner.GetPrimarySpecialization()); } if (needSave) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ITEM_INSTANCE_AZERITE_ON_LOAD); stmt.AddValue(0, azeriteData.Xp); stmt.AddValue(1, azeriteData.KnowledgeLevel); stmt.AddValue(2, GetGUID().GetCounter()); DB.Characters.Execute(stmt); } }
void LoadInstanceData(uint instanceId) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_SCENARIO_INSTANCE_CRITERIA_FOR_INSTANCE); stmt.AddValue(0, instanceId); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { SQLTransaction trans = new(); long now = GameTime.GetGameTime(); List <CriteriaTree> criteriaTrees = new(); do { uint id = result.Read <uint>(0); ulong counter = result.Read <ulong>(1); long date = result.Read <long>(2); Criteria criteria = Global.CriteriaMgr.GetCriteria(id); if (criteria == null) { // Removing non-existing criteria data for all instances Log.outError(LogFilter.Scenario, "Removing scenario criteria {0} data from the table `instance_scenario_progress`.", id); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_SCENARIO_INSTANCE_CRITERIA); stmt.AddValue(0, instanceId); stmt.AddValue(1, id); trans.Append(stmt); continue; } if (criteria.Entry.StartTimer != 0 && (date + criteria.Entry.StartTimer) < now) { continue; } switch (criteria.Entry.Type) { // Blizzard appears to only stores creatures killed progress for unknown reasons. Either technical shortcoming or intentional case CriteriaType.KillCreature: break; default: continue; } SetCriteriaProgress(criteria, counter, null, ProgressType.Set); List <CriteriaTree> trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id); if (trees != null) { foreach (CriteriaTree tree in trees) { criteriaTrees.Add(tree); } } }while (result.NextRow()); DB.Characters.CommitTransaction(trans); foreach (CriteriaTree tree in criteriaTrees) { ScenarioStepRecord step = tree.ScenarioStep; if (step == null) { continue; } if (IsCompletedCriteriaTree(tree)) { SetStepState(step, ScenarioStepState.Done); } } } }
public override void SaveToDB(SQLTransaction trans) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE); stmt.AddValue(0, GetGUID().GetCounter()); trans.Append(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_MILESTONE_POWER); stmt.AddValue(0, GetGUID().GetCounter()); trans.Append(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE); stmt.AddValue(0, GetGUID().GetCounter()); trans.Append(stmt); switch (GetState()) { case ItemUpdateState.New: case ItemUpdateState.Changed: stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_ITEM_INSTANCE_AZERITE); stmt.AddValue(0, GetGUID().GetCounter()); stmt.AddValue(1, m_azeriteItemData.Xp); stmt.AddValue(2, m_azeriteItemData.Level); stmt.AddValue(3, m_azeriteItemData.KnowledgeLevel); int specIndex = 0; for (; specIndex < m_azeriteItemData.SelectedEssences.Size(); ++specIndex) { stmt.AddValue(4 + specIndex * 5, m_azeriteItemData.SelectedEssences[specIndex].SpecializationID); for (int j = 0; j < SharedConst.MaxAzeriteEssenceSlot; ++j) { stmt.AddValue(5 + specIndex * 5 + j, m_azeriteItemData.SelectedEssences[specIndex].AzeriteEssenceID[j]); } } for (; specIndex < PlayerConst.MaxSpecializations; ++specIndex) { stmt.AddValue(4 + specIndex * 5, 0); for (int j = 0; j < SharedConst.MaxAzeriteEssenceSlot; ++j) { stmt.AddValue(5 + specIndex * 5 + j, 0); } } trans.Append(stmt); foreach (uint azeriteItemMilestonePowerId in m_azeriteItemData.UnlockedEssenceMilestones) { stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_ITEM_INSTANCE_AZERITE_MILESTONE_POWER); stmt.AddValue(0, GetGUID().GetCounter()); stmt.AddValue(1, azeriteItemMilestonePowerId); trans.Append(stmt); } foreach (var azeriteEssence in m_azeriteItemData.UnlockedEssences) { stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_ITEM_INSTANCE_AZERITE_UNLOCKED_ESSENCE); stmt.AddValue(0, GetGUID().GetCounter()); stmt.AddValue(1, azeriteEssence.AzeriteEssenceID); stmt.AddValue(2, azeriteEssence.Rank); trans.Append(stmt); } break; } base.SaveToDB(trans); }
void HandleOpenItem(OpenItem packet) { Player player = GetPlayer(); // ignore for remote control state if (player.m_unitMovedByMe != player) { return; } Item item = player.GetItemByPos(packet.Slot, packet.PackSlot); if (!item) { player.SendEquipError(InventoryResult.ItemNotFound); return; } ItemTemplate proto = item.GetTemplate(); if (proto == null) { player.SendEquipError(InventoryResult.ItemNotFound, item); return; } // Verify that the bag is an actual bag or wrapped item that can be used "normally" if (!proto.GetFlags().HasAnyFlag(ItemFlags.HasLoot) && !item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped)) { player.SendEquipError(InventoryResult.ClientLockedOut, item); Log.outError(LogFilter.Network, "Possible hacking attempt: Player {0} [guid: {1}] tried to open item [guid: {2}, entry: {3}] which is not openable!", player.GetName(), player.GetGUID().ToString(), item.GetGUID().ToString(), proto.GetId()); return; } // locked item uint lockId = proto.GetLockID(); if (lockId != 0) { LockRecord lockInfo = CliDB.LockStorage.LookupByKey(lockId); if (lockInfo == null) { player.SendEquipError(InventoryResult.ItemLocked, item); Log.outError(LogFilter.Network, "WORLD:OpenItem: item [guid = {0}] has an unknown lockId: {1}!", item.GetGUID().ToString(), lockId); return; } // was not unlocked yet if (item.IsLocked()) { player.SendEquipError(InventoryResult.ItemLocked, item); return; } } if (item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped))// wrapped? { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_GIFT_BY_ITEM); stmt.AddValue(0, item.GetGUID().GetCounter()); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { uint entry = result.Read <uint>(0); uint flags = result.Read <uint>(1); item.SetUInt64Value(ItemFields.GiftCreator, 0); item.SetEntry(entry); item.SetUInt32Value(ItemFields.Flags, flags); item.SetState(ItemUpdateState.Changed, player); } else { Log.outError(LogFilter.Network, "Wrapped item {0} don't have record in character_gifts table and will deleted", item.GetGUID().ToString()); player.DestroyItem(item.GetBagSlot(), item.GetSlot(), true); return; } stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GIFT); stmt.AddValue(0, item.GetGUID().GetCounter()); DB.Characters.Execute(stmt); } else { player.SendLoot(item.GetGUID(), LootType.Corpse); } }
void HandleCalendarEventInvite(CalendarEventInvite calendarEventInvite) { ObjectGuid playerGuid = GetPlayer().GetGUID(); ObjectGuid inviteeGuid = ObjectGuid.Empty; Team inviteeTeam = 0; ulong inviteeGuildId = 0; Player player = Global.ObjAccessor.FindPlayerByName(calendarEventInvite.Name); if (player) { // Invitee is online inviteeGuid = player.GetGUID(); inviteeTeam = player.GetTeam(); inviteeGuildId = player.GetGuildId(); } else { // Invitee offline, get data from database PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GUID_RACE_ACC_BY_NAME); stmt.AddValue(0, calendarEventInvite.Name); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { inviteeGuid = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0)); inviteeTeam = Player.TeamForRace((Race)result.Read <byte>(1)); inviteeGuildId = Player.GetGuildIdFromDB(inviteeGuid); } } if (inviteeGuid.IsEmpty()) { Global.CalendarMgr.SendCalendarCommandResult(playerGuid, CalendarError.PlayerNotFound); return; } if (GetPlayer().GetTeam() != inviteeTeam && !WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionCalendar)) { Global.CalendarMgr.SendCalendarCommandResult(playerGuid, CalendarError.NotAllied); return; } SQLResult result1 = DB.Characters.Query("SELECT flags FROM character_social WHERE guid = {0} AND friend = {1}", inviteeGuid, playerGuid); if (!result1.IsEmpty()) { if (Convert.ToBoolean(result1.Read <byte>(0) & (byte)SocialFlag.Ignored)) { Global.CalendarMgr.SendCalendarCommandResult(playerGuid, CalendarError.IgnoringYouS, calendarEventInvite.Name); return; } } if (!calendarEventInvite.Creating) { CalendarEvent calendarEvent = Global.CalendarMgr.GetEvent(calendarEventInvite.EventID); if (calendarEvent != null) { if (calendarEvent.IsGuildEvent() && calendarEvent.GuildId == inviteeGuildId) { // we can't invite guild members to guild events Global.CalendarMgr.SendCalendarCommandResult(playerGuid, CalendarError.NoGuildInvites); return; } CalendarInvite invite = new CalendarInvite(Global.CalendarMgr.GetFreeInviteId(), calendarEventInvite.EventID, inviteeGuid, playerGuid, SharedConst.CalendarDefaultResponseTime, CalendarInviteStatus.Invited, CalendarModerationRank.Player, ""); Global.CalendarMgr.AddInvite(calendarEvent, invite); } else { Global.CalendarMgr.SendCalendarCommandResult(playerGuid, CalendarError.EventInvalid); } } else { if (calendarEventInvite.IsSignUp && inviteeGuildId == GetPlayer().GetGuildId()) { Global.CalendarMgr.SendCalendarCommandResult(playerGuid, CalendarError.NoGuildInvites); return; } CalendarInvite invite = new CalendarInvite(calendarEventInvite.EventID, 0, inviteeGuid, playerGuid, SharedConst.CalendarDefaultResponseTime, CalendarInviteStatus.Invited, CalendarModerationRank.Player, ""); Global.CalendarMgr.SendCalendarEventInvite(invite); } }
public AccountOpResult DeleteAccount(uint accountId) { // Check if accounts exists PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_BY_ID); stmt.AddValue(0, accountId); SQLResult result = DB.Login.Query(stmt); if (result.IsEmpty()) { return(AccountOpResult.NameNotExist); } // Obtain accounts characters stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARS_BY_ACCOUNT_ID); stmt.AddValue(0, accountId); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { do { ObjectGuid guid = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0)); // Kick if player is online Player p = Global.ObjAccessor.FindPlayer(guid); if (p) { WorldSession s = p.GetSession(); s.KickPlayer(); // mark session to remove at next session list update s.LogoutPlayer(false); // logout player without waiting next session list update } Player.DeleteFromDB(guid, accountId, false); // no need to update realm characters } while (result.NextRow()); } // table realm specific but common for all characters of account for realm stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_TUTORIALS); stmt.AddValue(0, accountId); DB.Characters.Execute(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_ACCOUNT_DATA); stmt.AddValue(0, accountId); DB.Characters.Execute(stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CHARACTER_BAN); stmt.AddValue(0, accountId); DB.Characters.Execute(stmt); SQLTransaction trans = new SQLTransaction(); stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_ACCOUNT); stmt.AddValue(0, accountId); trans.Append(stmt); stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_ACCOUNT_ACCESS); stmt.AddValue(0, accountId); trans.Append(stmt); stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_REALM_CHARACTERS); stmt.AddValue(0, accountId); trans.Append(stmt); stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_ACCOUNT_BANNED); stmt.AddValue(0, accountId); trans.Append(stmt); stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_ACCOUNT_MUTED); stmt.AddValue(0, accountId); trans.Append(stmt); DB.Login.CommitTransaction(trans); return(AccountOpResult.Ok); }
static void Main(string[] args) { var TestDB = new TestDatabase(); DatabaseLoader loader = new DatabaseLoader(false); loader.AddDatabase(TestDB, new MySqlConnectionInfo() { Host = "127.0.0.1", Port = "3306", Username = "******", Password = "******", Database = "asyncsql_test" }, 5); var dbLoaded = loader.Load(); if (!dbLoaded) { Console.WriteLine("test db load failed!"); return; } var success = TestDB.DirectExecute("SELECT 1 FROM account"); if (success) { Console.WriteLine("Direct execute sql successfully."); } PreparedStatement stmt = TestDB.GetPreparedStatement(LoginStatements.INS_ACCOUNT); stmt.AddValue(0, "asyncsql1"); TestDB.DirectExecute(stmt); stmt = TestDB.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_LIST_BY_NAME); stmt.AddValue(0, "asyncsql1"); var result = TestDB.Query(stmt); if (result.IsEmpty()) { Console.WriteLine("Query failed."); } else { uint accountId = result.Read <uint>(0); string accountName = result.Read <string>(1); Console.WriteLine("Query success. accountId: {0}, accountName: {1}", accountId, accountName); } // Next teset async query AsyncCallbackProcessor <QueryCallback> queryProcessor = new AsyncCallbackProcessor <QueryCallback>(); for (int i = 0; i < 5; i++) { stmt = TestDB.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_LIST); queryProcessor.AddCallback(TestDB.AsyncQuery(stmt).WithCallback(async result => { if (!result.IsEmpty()) { do { var accountId = result.Read <uint>(0); string accountName = result.Read <string>(1); Console.WriteLine("Async execute query {0} - accountId: {1}, accountName: {2}", stmt.CommandText, accountId, accountName); } while (result.NextRow()); } await AsyncFoo(); Console.WriteLine("Async query callback DONE."); })); } // Process async queries in another thread. var updateThread = new Thread(() => { while (true) { queryProcessor.ProcessReadyCallbacks(); Thread.Sleep(500); } }) { IsBackground = true, Name = "AsyncQueryThread" }; updateThread.Start(); Thread.Sleep(2000); TestDB.Dispose(); }
static bool HandleListMailCommand(StringArguments args, CommandHandler handler) { if (args.Empty()) { return(false); } Player target; ObjectGuid targetGuid; string targetName; PreparedStatement stmt = null; ObjectGuid parseGUID = ObjectGuid.Create(HighGuid.Player, args.NextUInt64()); if (ObjectManager.GetPlayerNameByGUID(parseGUID, out targetName)) { target = Global.ObjAccessor.FindPlayer(parseGUID); targetGuid = parseGUID; } else if (!handler.extractPlayerTarget(args, out target, out targetGuid, out targetName)) { return(false); } stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL_LIST_COUNT); stmt.AddValue(0, targetGuid.GetCounter()); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { uint countMail = result.Read <uint>(0); string nameLink = handler.playerLink(targetName); handler.SendSysMessage(CypherStrings.ListMailHeader, countMail, nameLink, targetGuid.ToString()); handler.SendSysMessage(CypherStrings.AccountListBar); stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL_LIST_INFO); stmt.AddValue(0, targetGuid.GetCounter()); SQLResult result1 = DB.Characters.Query(stmt); if (!result1.IsEmpty()) { do { uint messageId = result1.Read <uint>(0); ulong senderId = result1.Read <ulong>(1); string sender = result1.Read <string>(2); ulong receiverId = result1.Read <ulong>(3); string receiver = result1.Read <string>(4); string subject = result1.Read <string>(5); long deliverTime = result1.Read <uint>(6); long expireTime = result1.Read <uint>(7); ulong money = result1.Read <ulong>(8); byte hasItem = result1.Read <byte>(9); uint gold = (uint)(money / MoneyConstants.Gold); uint silv = (uint)(money % MoneyConstants.Gold) / MoneyConstants.Silver; uint copp = (uint)(money % MoneyConstants.Gold) % MoneyConstants.Silver; string receiverStr = handler.playerLink(receiver); string senderStr = handler.playerLink(sender); handler.SendSysMessage(CypherStrings.ListMailInfo1, messageId, subject, gold, silv, copp); handler.SendSysMessage(CypherStrings.ListMailInfo2, senderStr, senderId, receiverStr, receiverId); handler.SendSysMessage(CypherStrings.ListMailInfo3, Time.UnixTimeToDateTime(deliverTime).ToLongDateString(), Time.UnixTimeToDateTime(expireTime).ToLongDateString()); if (hasItem == 1) { SQLResult result2 = DB.Characters.Query("SELECT item_guid FROM mail_items WHERE mail_id = '{0}'", messageId); if (!result2.IsEmpty()) { do { uint item_guid = result2.Read <uint>(0); stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL_LIST_ITEMS); stmt.AddValue(0, item_guid); SQLResult result3 = DB.Characters.Query(stmt); if (!result3.IsEmpty()) { do { uint item_entry = result3.Read <uint>(0); uint item_count = result3.Read <uint>(1); SQLResult result4 = DB.World.Query("SELECT name, quality FROM item_template WHERE entry = '{0}'", item_entry); string item_name = result4.Read <string>(0); int item_quality = result4.Read <byte>(1); if (handler.GetSession() != null) { uint color = ItemConst.ItemQualityColors[item_quality]; string itemStr = "|c" + color + "|Hitem:" + item_entry + ":0:0:0:0:0:0:0:0:0|h[" + item_name + "]|h|r"; handler.SendSysMessage(CypherStrings.ListMailInfoItem, itemStr, item_entry, item_guid, item_count); } else { handler.SendSysMessage(CypherStrings.ListMailInfoItem, item_name, item_entry, item_guid, item_count); } }while (result3.NextRow()); } }while (result2.NextRow()); } } handler.SendSysMessage(CypherStrings.AccountListBar); }while (result1.NextRow()); } else { handler.SendSysMessage(CypherStrings.ListMailNotFound); } return(true); } else { handler.SendSysMessage(CypherStrings.ListMailNotFound); } return(true); }
public BattlenetRpcErrorCode HandleVerifyWebCredentials(Bgs.Protocol.Authentication.V1.VerifyWebCredentialsRequest verifyWebCredentialsRequest) { if (verifyWebCredentialsRequest.WebCredentials.IsEmpty) { return(BattlenetRpcErrorCode.Denied); } PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_ACCOUNT_INFO); stmt.AddValue(0, verifyWebCredentialsRequest.WebCredentials.ToStringUtf8()); SQLResult result = DB.Login.Query(stmt); if (result.IsEmpty()) { return(BattlenetRpcErrorCode.Denied); } _accountInfo = new AccountInfo(); _accountInfo.LoadResult(result); if (_accountInfo.LoginTicketExpiry < Time.UnixTime) { return(BattlenetRpcErrorCode.TimedOut); } stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID); stmt.AddValue(0, _accountInfo.Id); SQLResult characterCountsResult = DB.Login.Query(stmt); if (!characterCountsResult.IsEmpty()) { do { RealmHandle realmId = new RealmHandle(characterCountsResult.Read <byte>(3), characterCountsResult.Read <byte>(4), characterCountsResult.Read <uint>(2)); _accountInfo.GameAccounts[characterCountsResult.Read <uint>(0)].CharacterCounts[realmId.GetAddress()] = characterCountsResult.Read <byte>(1); } while (characterCountsResult.NextRow()); } stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_LAST_PLAYER_CHARACTERS); stmt.AddValue(0, _accountInfo.Id); SQLResult lastPlayerCharactersResult = DB.Login.Query(stmt); if (!lastPlayerCharactersResult.IsEmpty()) { do { RealmHandle realmId = new RealmHandle(lastPlayerCharactersResult.Read <byte>(1), lastPlayerCharactersResult.Read <byte>(2), lastPlayerCharactersResult.Read <uint>(3)); LastPlayedCharacterInfo lastPlayedCharacter = new LastPlayedCharacterInfo(); lastPlayedCharacter.RealmId = realmId; lastPlayedCharacter.CharacterName = lastPlayerCharactersResult.Read <string>(4); lastPlayedCharacter.CharacterGUID = lastPlayerCharactersResult.Read <ulong>(5); lastPlayedCharacter.LastPlayedTime = lastPlayerCharactersResult.Read <uint>(6); _accountInfo.GameAccounts[lastPlayerCharactersResult.Read <uint>(0)].LastPlayedCharacters[realmId.GetSubRegionAddress()] = lastPlayedCharacter; } while (lastPlayerCharactersResult.NextRow()); } string ip_address = GetRemoteIpAddress().ToString(); // If the IP is 'locked', check that the player comes indeed from the correct IP address if (_accountInfo.IsLockedToIP) { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is locked to IP - '{1}' is logging in from '{2}'", _accountInfo.Login, _accountInfo.LastIP, ip_address); if (_accountInfo.LastIP != ip_address) { return(BattlenetRpcErrorCode.RiskAccountLocked); } } else { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is not locked to ip", _accountInfo.Login); if (_accountInfo.LockCountry.IsEmpty() || _accountInfo.LockCountry == "00") { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is not locked to country", _accountInfo.Login); } else if (!_accountInfo.LockCountry.IsEmpty() && !_ipCountry.IsEmpty()) { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is locked to country: '{1}' Player country is '{2}'", _accountInfo.Login, _accountInfo.LockCountry, _ipCountry); if (_ipCountry != _accountInfo.LockCountry) { return(BattlenetRpcErrorCode.RiskAccountLocked); } } } // If the account is banned, reject the logon attempt if (_accountInfo.IsBanned) { if (_accountInfo.IsPermanenetlyBanned) { Log.outDebug(LogFilter.Session, "{0} Session.HandleVerifyWebCredentials: Banned account {1} tried to login!", GetClientInfo(), _accountInfo.Login); return(BattlenetRpcErrorCode.GameAccountBanned); } else { Log.outDebug(LogFilter.Session, "{0} Session.HandleVerifyWebCredentials: Temporarily banned account {1} tried to login!", GetClientInfo(), _accountInfo.Login); return(BattlenetRpcErrorCode.GameAccountSuspended); } } Bgs.Protocol.Authentication.V1.LogonResult logonResult = new Bgs.Protocol.Authentication.V1.LogonResult(); logonResult.ErrorCode = 0; logonResult.AccountId = new EntityId(); logonResult.AccountId.Low = _accountInfo.Id; logonResult.AccountId.High = 0x100000000000000; foreach (var pair in _accountInfo.GameAccounts) { EntityId gameAccountId = new EntityId(); gameAccountId.Low = pair.Value.Id; gameAccountId.High = 0x200000200576F57; logonResult.GameAccountId.Add(gameAccountId); } if (!_ipCountry.IsEmpty()) { logonResult.GeoipCountry = _ipCountry; } logonResult.SessionKey = ByteString.CopyFrom(new byte[64].GenerateRandomKey(64)); _authed = true; SendRequest((uint)OriginalHash.AuthenticationListener, 5, logonResult); return(BattlenetRpcErrorCode.Ok); }
void LoadResetTimes() { long now = Time.UnixTime; long today = (now / Time.Day) * Time.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 Dictionary <uint, Tuple <uint, long> > instResetTime = new(); // index instance ids by map/difficulty pairs for fast reset warning send MultiMap <uint, uint> mapDiffResetInstances = new(); SQLResult result = DB.Characters.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC"); if (!result.IsEmpty()) { do { uint instanceId = result.Read <uint>(0); // Mark instance id as being used Global.MapMgr.RegisterInstanceId(instanceId); long resettime = result.Read <long>(3); if (resettime != 0) { uint mapid = result.Read <ushort>(1); uint difficulty = result.Read <byte>(2); instResetTime[instanceId] = Tuple.Create(MathFunctions.MakePair32(mapid, difficulty), resettime); mapDiffResetInstances.Add(MathFunctions.MakePair32(mapid, difficulty), instanceId); } }while (result.NextRow()); // schedule the reset times foreach (var pair in instResetTime) { if (pair.Value.Item2 > now) { ScheduleReset(true, pair.Value.Item2, new InstResetEvent(0, MathFunctions.Pair32_LoPart(pair.Value.Item1), (Difficulty)MathFunctions.Pair32_HiPart(pair.Value.Item1), pair.Key)); } } } // load the global respawn times for raid/heroic instances uint diff = (uint)(WorldConfig.GetIntValue(WorldCfg.InstanceResetTimeHour) * Time.Hour); result = DB.Characters.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if (!result.IsEmpty()) { do { uint mapid = result.Read <ushort>(0); Difficulty difficulty = (Difficulty)result.Read <byte>(1); long oldresettime = result.Read <long>(2); MapDifficultyRecord mapDiff = Global.DB2Mgr.GetMapDifficultyData(mapid, difficulty); if (mapDiff == null) { Log.outError(LogFilter.Server, "InstanceSaveManager.LoadResetTimes: invalid mapid({0})/difficulty({1}) pair in instance_reset!", mapid, difficulty); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); DB.Characters.DirectExecute(stmt); continue; } // update the reset time if the hour in the configs changes long newresettime = (oldresettime / Time.Day) * Time.Day + diff; if (oldresettime != newresettime) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, newresettime); stmt.AddValue(1, mapid); stmt.AddValue(2, (byte)difficulty); DB.Characters.DirectExecute(stmt); } InitializeResetTimeFor(mapid, difficulty, newresettime); } while (result.NextRow()); } // 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 foreach (var mapDifficultyPair in Global.DB2Mgr.GetMapDifficulties()) { uint mapid = mapDifficultyPair.Key; foreach (var difficultyPair in mapDifficultyPair.Value) { Difficulty difficulty = (Difficulty)difficultyPair.Key; MapDifficultyRecord mapDiff = difficultyPair.Value; if (mapDiff.GetRaidDuration() == 0) { continue; } // the reset_delay must be at least one day uint period = (uint)(((mapDiff.GetRaidDuration() * WorldConfig.GetFloatValue(WorldCfg.RateInstanceResetTime)) / Time.Day) * Time.Day); if (period < Time.Day) { period = Time.Day; } long t = GetResetTimeFor(mapid, difficulty); if (t == 0) { // initialize the reset time t = today + period + diff; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); stmt.AddValue(2, t); DB.Characters.DirectExecute(stmt); } if (t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / Time.Day) * Time.Day; t += ((today - t) / period + 1) * period + diff; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, t); stmt.AddValue(1, mapid); stmt.AddValue(2, (byte)difficulty); DB.Characters.DirectExecute(stmt); } InitializeResetTimeFor(mapid, difficulty, t); // schedule the global reset/warning byte type; for (type = 1; type < 4; ++type) { if (t - ResetTimeDelay[type - 1] > now) { break; } } ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, 0)); var range = mapDiffResetInstances.LookupByKey(MathFunctions.MakePair32(mapid, (uint)difficulty)); foreach (var id in range) { ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, id)); } } } }
BattlenetRpcErrorCode GetRealmListTicket(Dictionary <string, Variant> Params, Bgs.Protocol.GameUtilities.V1.ClientResponse response) { Variant identity = GetParam(Params, "Param_Identity"); if (identity != null) { var realmListTicketIdentity = Json.CreateObject <RealmListTicketIdentity>(identity.BlobValue.ToStringUtf8(), true); var gameAccountInfo = _accountInfo.GameAccounts.LookupByKey(realmListTicketIdentity.GameAccountId); if (gameAccountInfo != null) { _gameAccountInfo = gameAccountInfo; } } if (_gameAccountInfo == null) { return(BattlenetRpcErrorCode.UtilServerInvalidIdentityArgs); } if (_gameAccountInfo.IsPermanenetlyBanned) { return(BattlenetRpcErrorCode.GameAccountBanned); } else if (_gameAccountInfo.IsBanned) { return(BattlenetRpcErrorCode.GameAccountSuspended); } bool clientInfoOk = false; Variant clientInfo = GetParam(Params, "Param_ClientInfo"); if (clientInfo != null) { var realmListTicketClientInformation = Json.CreateObject <RealmListTicketClientInformation>(clientInfo.BlobValue.ToStringUtf8(), true); clientInfoOk = true; int i = 0; foreach (var b in realmListTicketClientInformation.Info.Secret.Select(Convert.ToByte)) { _clientSecret[i++] = b; } } if (!clientInfoOk) { return(BattlenetRpcErrorCode.WowServicesDeniedRealmListTicket); } PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_BNET_LAST_LOGIN_INFO); stmt.AddValue(0, GetRemoteIpAddress().ToString()); stmt.AddValue(1, Enum.Parse(typeof(LocaleConstant), _locale)); stmt.AddValue(2, _os); stmt.AddValue(3, _accountInfo.Id); DB.Login.Execute(stmt); var attribute = new Bgs.Protocol.Attribute(); attribute.Name = "Param_RealmListTicket"; attribute.Value = new Variant(); attribute.Value.BlobValue = ByteString.CopyFrom("AuthRealmListTicket", System.Text.Encoding.UTF8); response.Attribute.Add(attribute); return(BattlenetRpcErrorCode.Ok); }
static bool HandleGroupListCommand(StringArguments args, CommandHandler handler) { // Get ALL the variables! Player playerTarget; ObjectGuid guidTarget; string nameTarget; string zoneName = ""; string onlineState; // Parse the guid to uint32... ObjectGuid parseGUID = ObjectGuid.Create(HighGuid.Player, args.NextUInt64()); // ... and try to extract a player out of it. if (Global.CharacterCacheStorage.GetCharacterNameByGuid(parseGUID, out nameTarget)) { playerTarget = Global.ObjAccessor.FindPlayer(parseGUID); guidTarget = parseGUID; } // If not, we return false and end right away. else if (!handler.ExtractPlayerTarget(args, out playerTarget, out guidTarget, out nameTarget)) { return(false); } // Next, we need a group. So we define a group variable. Group groupTarget = null; // We try to extract a group from an online player. if (playerTarget) { groupTarget = playerTarget.GetGroup(); } // If not, we extract it from the SQL. if (!groupTarget) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_GROUP_MEMBER); stmt.AddValue(0, guidTarget.GetCounter()); SQLResult resultGroup = DB.Characters.Query(stmt); if (!resultGroup.IsEmpty()) { groupTarget = Global.GroupMgr.GetGroupByDbStoreId(resultGroup.Read <uint>(0)); } } // If both fails, players simply has no party. Return false. if (!groupTarget) { handler.SendSysMessage(CypherStrings.GroupNotInGroup, nameTarget); return(false); } // We get the group members after successfully detecting a group. var members = groupTarget.GetMemberSlots(); // To avoid a cluster f**k, namely trying multiple queries to simply get a group member count... handler.SendSysMessage(CypherStrings.GroupType, (groupTarget.IsRaidGroup() ? "raid" : "party"), members.Count); // ... we simply move the group type and member count print after retrieving the slots and simply output it's size. // While rather dirty codestyle-wise, it saves space (if only a little). For each member, we look several informations up. foreach (var slot in members) { // Check for given flag and assign it to that iterator string flags = ""; if (slot.flags.HasAnyFlag(GroupMemberFlags.Assistant)) { flags = "Assistant"; } if (slot.flags.HasAnyFlag(GroupMemberFlags.MainTank)) { if (!string.IsNullOrEmpty(flags)) { flags += ", "; } flags += "MainTank"; } if (slot.flags.HasAnyFlag(GroupMemberFlags.MainAssist)) { if (!string.IsNullOrEmpty(flags)) { flags += ", "; } flags += "MainAssist"; } if (string.IsNullOrEmpty(flags)) { flags = "None"; } // Check if iterator is online. If is... Player p = Global.ObjAccessor.FindPlayer(slot.guid); string phases = ""; if (p && p.IsInWorld) { // ... than, it prints information like "is online", where he is, etc... onlineState = "online"; phases = PhasingHandler.FormatPhases(p.GetPhaseShift()); AreaTableRecord area = CliDB.AreaTableStorage.LookupByKey(p.GetAreaId()); if (area != null) { AreaTableRecord zone = CliDB.AreaTableStorage.LookupByKey(area.ParentAreaID); if (zone != null) { zoneName = zone.AreaName[handler.GetSessionDbcLocale()]; } } } else { // ... else, everything is set to offline or neutral values. zoneName = "<ERROR>"; onlineState = "Offline"; } // Now we can print those informations for every single member of each group! handler.SendSysMessage(CypherStrings.GroupPlayerNameGuid, slot.name, onlineState, zoneName, phases, slot.guid.ToString(), flags, LFGQueue.GetRolesString(slot.roles)); } // And finish after every iterator is done. return(true); }
void HandleSendMail(SendMail packet) { if (packet.Info.Attachments.Count > SharedConst.MaxMailItems) // client limit { GetPlayer().SendMailResult(0, MailResponseType.Send, MailResponseResult.TooManyAttachments); return; } if (!CanOpenMailBox(packet.Info.Mailbox)) { return; } if (string.IsNullOrEmpty(packet.Info.Target)) { return; } Player player = GetPlayer(); if (player.getLevel() < WorldConfig.GetIntValue(WorldCfg.MailLevelReq)) { SendNotification(CypherStrings.MailSenderReq, WorldConfig.GetIntValue(WorldCfg.MailLevelReq)); return; } ObjectGuid receiverGuid = ObjectGuid.Empty; if (ObjectManager.NormalizePlayerName(ref packet.Info.Target)) { receiverGuid = ObjectManager.GetPlayerGUIDByName(packet.Info.Target); } if (receiverGuid.IsEmpty()) { Log.outInfo(LogFilter.Network, "Player {0} is sending mail to {1} (GUID: not existed!) with subject {2}" + "and body {3} includes {4} items, {5} copper and {6} COD copper with StationeryID = {7}", GetPlayerInfo(), packet.Info.Target, packet.Info.Subject, packet.Info.Body, packet.Info.Attachments.Count, packet.Info.SendMoney, packet.Info.Cod, packet.Info.StationeryID); player.SendMailResult(0, MailResponseType.Send, MailResponseResult.RecipientNotFound); return; } if (packet.Info.SendMoney < 0) { GetPlayer().SendMailResult(0, MailResponseType.Send, MailResponseResult.InternalError); Log.outWarn(LogFilter.Server, "Player {0} attempted to send mail to {1} ({2}) with negative money value (SendMoney: {3})", GetPlayerInfo(), packet.Info.Target, receiverGuid.ToString(), packet.Info.SendMoney); return; } if (packet.Info.Cod < 0) { GetPlayer().SendMailResult(0, MailResponseType.Send, MailResponseResult.InternalError); Log.outWarn(LogFilter.Server, "Player {0} attempted to send mail to {1} ({2}) with negative COD value (Cod: {3})", GetPlayerInfo(), packet.Info.Target, receiverGuid.ToString(), packet.Info.Cod); return; } Log.outInfo(LogFilter.Network, "Player {0} is sending mail to {1} ({2}) with subject {3} and body {4}" + "includes {5} items, {6} copper and {7} COD copper with StationeryID = {8}", GetPlayerInfo(), packet.Info.Target, receiverGuid.ToString(), packet.Info.Subject, packet.Info.Body, packet.Info.Attachments.Count, packet.Info.SendMoney, packet.Info.Cod, packet.Info.StationeryID); if (player.GetGUID() == receiverGuid) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.CannotSendToSelf); return; } uint cost = (uint)(!packet.Info.Attachments.Empty() ? 30 * packet.Info.Attachments.Count : 30); // price hardcoded in client long reqmoney = cost + packet.Info.SendMoney; // Check for overflow if (reqmoney < packet.Info.SendMoney) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.NotEnoughMoney); return; } if (!player.HasEnoughMoney(reqmoney) && !player.IsGameMaster()) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.NotEnoughMoney); return; } Player receiver = Global.ObjAccessor.FindPlayer(receiverGuid); Team receiverTeam = 0; byte mailsCount = 0; //do not allow to send to one player more than 100 mails byte receiverLevel = 0; uint receiverAccountId = 0; if (receiver) { receiverTeam = receiver.GetTeam(); mailsCount = (byte)receiver.GetMails().Count; receiverLevel = (byte)receiver.getLevel(); receiverAccountId = receiver.GetSession().GetAccountId(); } else { receiverTeam = ObjectManager.GetPlayerTeamByGUID(receiverGuid); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL_COUNT); stmt.AddValue(0, receiverGuid.GetCounter()); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { mailsCount = (byte)result.Read <ulong>(0); } stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHAR_LEVEL); stmt.AddValue(0, receiverGuid.GetCounter()); result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { receiverLevel = result.Read <byte>(0); } receiverAccountId = ObjectManager.GetPlayerAccountIdByGUID(receiverGuid); } // do not allow to have more than 100 mails in mailbox.. mails count is in opcode byte!!! - so max can be 255.. if (mailsCount > 100) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.RecipientCapReached); return; } // test the receiver's Faction... or all items are account bound bool accountBound = !packet.Info.Attachments.Empty(); foreach (var att in packet.Info.Attachments) { Item item = player.GetItemByGuid(att.ItemGUID); if (item) { ItemTemplate itemProto = item.GetTemplate(); if (itemProto == null || !itemProto.GetFlags().HasAnyFlag(ItemFlags.IsBoundToAccount)) { accountBound = false; break; } } } if (!accountBound && player.GetTeam() != receiverTeam && !HasPermission(RBACPermissions.TwoSideInteractionMail)) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.NotYourTeam); return; } if (receiverLevel < WorldConfig.GetIntValue(WorldCfg.MailLevelReq)) { SendNotification(CypherStrings.MailReceiverReq, WorldConfig.GetIntValue(WorldCfg.MailLevelReq)); return; } List <Item> items = new List <Item>(); foreach (var att in packet.Info.Attachments) { if (att.ItemGUID.IsEmpty()) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.MailAttachmentInvalid); return; } Item item = player.GetItemByGuid(att.ItemGUID); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.MailAttachmentInvalid); return; } if (!item.CanBeTraded(true)) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.MailBoundItem); return; } if (item.IsBoundAccountWide() && item.IsSoulBound() && player.GetSession().GetAccountId() != receiverAccountId) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.NotSameAccount); return; } if (item.GetTemplate().GetFlags().HasAnyFlag(ItemFlags.Conjured) || item.GetUInt32Value(ItemFields.Duration) != 0) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.MailBoundItem); return; } if (packet.Info.Cod != 0 && item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped)) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.CantSendWrappedCod); return; } if (item.IsNotEmptyBag()) { player.SendMailResult(0, MailResponseType.Send, MailResponseResult.EquipError, InventoryResult.DestroyNonemptyBag); return; } items.Add(item); } player.SendMailResult(0, MailResponseType.Send, MailResponseResult.Ok); player.ModifyMoney(-reqmoney); player.UpdateCriteria(CriteriaTypes.GoldSpentForMail, cost); bool needItemDelay = false; MailDraft draft = new MailDraft(packet.Info.Subject, packet.Info.Body); SQLTransaction trans = new SQLTransaction(); if (!packet.Info.Attachments.Empty() || packet.Info.SendMoney > 0) { bool log = HasPermission(RBACPermissions.LogGmTrade); if (!packet.Info.Attachments.Empty()) { foreach (var item in items) { if (log) { Log.outCommand(GetAccountId(), "GM {0} ({1}) (Account: {2}) mail item: {3} (Entry: {4} Count: {5}) to player: {6} ({7}) (Account: {8})", GetPlayerName(), GetPlayer().GetGUID().ToString(), GetAccountId(), item.GetTemplate().GetName(), item.GetEntry(), item.GetCount(), packet.Info.Target, receiverGuid.ToString(), receiverAccountId); } item.SetNotRefundable(GetPlayer()); // makes the item no longer refundable player.MoveItemFromInventory(item.GetBagSlot(), item.GetSlot(), true); item.DeleteFromInventoryDB(trans); // deletes item from character's inventory item.SetOwnerGUID(receiverGuid); item.SetState(ItemUpdateState.Changed); item.SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay needItemDelay = player.GetSession().GetAccountId() != receiverAccountId; } if (log && packet.Info.SendMoney > 0) { Log.outCommand(GetAccountId(), "GM {0} ({1}) (Account: {{2}) mail money: {3} to player: {4} ({5}) (Account: {6})", GetPlayerName(), GetPlayer().GetGUID().ToString(), GetAccountId(), packet.Info.SendMoney, packet.Info.Target, receiverGuid.ToString(), receiverAccountId); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint deliver_delay = needItemDelay ? WorldConfig.GetUIntValue(WorldCfg.MailDeliveryDelay) : 0; // Mail sent between guild members arrives instantly Guild guild = Global.GuildMgr.GetGuildById(player.GetGuildId()); if (guild) { if (guild.IsMember(receiverGuid)) { deliver_delay = 0; } } // don't ask for COD if there are no items if (packet.Info.Attachments.Empty()) { packet.Info.Cod = 0; } // will delete item or place to receiver mail list draft.AddMoney((ulong)packet.Info.SendMoney).AddCOD((uint)packet.Info.Cod).SendMailTo(trans, new MailReceiver(receiver, receiverGuid.GetCounter()), new MailSender(player), string.IsNullOrEmpty(packet.Info.Body) ? MailCheckMask.Copied : MailCheckMask.HasBody, deliver_delay); player.SaveInventoryAndGoldToDB(trans); DB.Characters.CommitTransaction(trans); }
public void LogoutPlayer(bool save) { // finish pending transfers before starting the logout while (_player && _player.IsBeingTeleportedFar()) { HandleMoveWorldportAck(); } m_playerLogout = true; m_playerSave = save; if (_player) { if (!_player.GetLootGUID().IsEmpty()) { DoLootReleaseAll(); } // If the player just died before logging out, make him appear as a ghost //FIXME: logout must be delayed in case lost connection with client in time of combat if (GetPlayer().GetDeathTimer() != 0) { _player.getHostileRefManager().deleteReferences(); _player.BuildPlayerRepop(); _player.RepopAtGraveyard(); } else if (GetPlayer().HasAuraType(AuraType.SpiritOfRedemption)) { // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION _player.RemoveAurasByType(AuraType.ModShapeshift); _player.KillPlayer(); _player.BuildPlayerRepop(); _player.RepopAtGraveyard(); } else if (GetPlayer().HasPendingBind()) { _player.RepopAtGraveyard(); _player.SetPendingBind(0, 0); } //drop a flag if player is carrying it Battleground bg = GetPlayer().GetBattleground(); if (bg) { bg.EventPlayerLoggedOut(GetPlayer()); } // Teleport to home if the player is in an invalid instance if (!_player.m_InstanceValid && !_player.IsGameMaster()) { _player.TeleportTo(_player.GetHomebind()); } Global.OutdoorPvPMgr.HandlePlayerLeaveZone(_player, _player.GetZoneId()); for (uint i = 0; i < SharedConst.MaxPlayerBGQueues; ++i) { BattlegroundQueueTypeId bgQueueTypeId = GetPlayer().GetBattlegroundQueueTypeId(i); if (bgQueueTypeId != 0) { _player.RemoveBattlegroundQueueId(bgQueueTypeId); BattlegroundQueue queue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); queue.RemovePlayer(_player.GetGUID(), true); } } // Repop at GraveYard or other player far teleport will prevent saving player because of not present map // Teleport player immediately for correct player save while (_player.IsBeingTeleportedFar()) { HandleMoveWorldportAck(); } // If the player is in a guild, update the guild roster and broadcast a logout message to other guild members Guild guild = Global.GuildMgr.GetGuildById(_player.GetGuildId()); if (guild) { guild.HandleMemberLogout(this); } // Remove pet _player.RemovePet(null, PetSaveMode.AsCurrent, true); // Clear whisper whitelist _player.ClearWhisperWhiteList(); // empty buyback items and save the player in the database // some save parts only correctly work in case player present in map/player_lists (pets, etc) if (save) { int eslot; for (int j = InventorySlots.BuyBackStart; j < InventorySlots.BuyBackEnd; ++j) { eslot = j - InventorySlots.BuyBackStart; _player.SetGuidValue(PlayerFields.InvSlotHead + (j * 4), ObjectGuid.Empty); _player.SetUInt32Value(PlayerFields.BuyBackPrice1 + eslot, 0); _player.SetUInt32Value(PlayerFields.BuyBackTimestamp1 + eslot, 0); } _player.SaveToDB(); } // Leave all channels before player delete... _player.CleanupChannels(); // If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group. _player.UninviteFromGroup(); // remove player from the group if he is: // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) if (_player.GetGroup() && !_player.GetGroup().isRaidGroup() && m_Socket[(int)ConnectionType.Realm] != null) { _player.RemoveFromGroup(); } //! Send update to group and reset stored max enchanting level if (_player.GetGroup()) { _player.GetGroup().SendUpdate(); _player.GetGroup().ResetMaxEnchantingLevel(); } //! Broadcast a logout message to the player's friends Global.SocialMgr.SendFriendStatus(_player, FriendsResult.Offline, _player.GetGUID(), true); _player.RemoveSocial(); //! Call script hook before deletion Global.ScriptMgr.OnPlayerLogout(GetPlayer()); //! Remove the player from the world // the player may not be in the world when logging out // e.g if he got disconnected during a transfer to another map // calls to GetMap in this case may cause crashes GetPlayer().CleanupsBeforeDelete(); Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Logout Character:[{2}] (GUID: {3}) Level: {4}", GetAccountId(), GetRemoteAddress(), _player.GetName(), _player.GetGUID().ToString(), _player.getLevel()); Map map = GetPlayer().GetMap(); if (map != null) { map.RemovePlayerFromMap(GetPlayer(), true); } SetPlayer(null); //! Send the 'logout complete' packet to the client //! Client will respond by sending 3x CMSG_CANCEL_TRADE, which we currently dont handle LogoutComplete logoutComplete = new LogoutComplete(); SendPacket(logoutComplete); //! Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ACCOUNT_ONLINE); stmt.AddValue(0, GetAccountId()); DB.Characters.Execute(stmt); } if (m_Socket[(int)ConnectionType.Instance] != null) { m_Socket[(int)ConnectionType.Instance].CloseSocket(); m_Socket[(int)ConnectionType.Instance] = null; } m_playerLogout = false; m_playerSave = false; m_playerRecentlyLogout = true; SetLogoutStartTime(0); }
static bool HandleWpModifyCommand(StringArguments args, CommandHandler handler) { if (args.Empty()) { return(false); } // first arg: add del text emote spell waittime move string show = args.NextString(); if (string.IsNullOrEmpty(show)) { return(false); } // Check // Remember: "show" must also be the name of a column! if ((show != "delay") && (show != "action") && (show != "action_chance") && (show != "move_flag") && (show != "del") && (show != "move")) { return(false); } // Did user provide a GUID // or did the user select a creature? // . variable lowguid is filled with the GUID of the NPC uint pathid; uint point; Creature target = handler.GetSelectedCreature(); // User did select a visual waypoint? if (!target || target.GetEntry() != 1) { handler.SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r"); return(false); } // Check the creature PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_DATA_BY_WPGUID); stmt.AddValue(0, target.GetSpawnId()); SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.WaypointNotfoundsearch, target.GetGUID().ToString()); // Select waypoint number from database // Since we compare float values, we have to deal with // some difficulties. // Here we search for all waypoints that only differ in one from 1 thousand // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html string maxDiff = "0.01"; stmt = DB.World.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_DATA_BY_POS); stmt.AddValue(0, target.GetPositionX()); stmt.AddValue(1, maxDiff); stmt.AddValue(2, target.GetPositionY()); stmt.AddValue(3, maxDiff); stmt.AddValue(4, target.GetPositionZ()); stmt.AddValue(5, maxDiff); result = DB.World.Query(stmt); if (result.IsEmpty()) { handler.SendSysMessage(CypherStrings.WaypointNotfounddbproblem, target.GetGUID().ToString()); return(true); } } do { pathid = result.Read <uint>(0); point = result.Read <uint>(1); }while (result.NextRow()); // We have the waypoint number and the GUID of the "master npc" // Text is enclosed in "<>", all other arguments not string arg_str = args.NextString(); // Check for argument if (show != "del" && show != "move" && arg_str == null) { handler.SendSysMessage(CypherStrings.WaypointArgumentreq, show); return(false); } if (show == "del") { handler.SendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff{0}|r", pathid); target.DeleteFromDB(); target.AddObjectToRemoveList(); stmt = DB.World.GetPreparedStatement(WorldStatements.DEL_WAYPOINT_DATA); stmt.AddValue(0, pathid); stmt.AddValue(1, point); DB.World.Execute(stmt); stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_POINT); stmt.AddValue(0, pathid); stmt.AddValue(1, point); DB.World.Execute(stmt); handler.SendSysMessage(CypherStrings.WaypointRemoved); return(true); } // del if (show == "move") { handler.SendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff{0}|r", pathid); Player chr = handler.GetSession().GetPlayer(); Map map = chr.GetMap(); // What to do: // Move the visual spawnpoint // Respawn the owner of the waypoints target.DeleteFromDB(); target.AddObjectToRemoveList(); // re-create Creature creature = Creature.CreateCreature(1, map, chr.GetPosition()); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); return(false); } PhasingHandler.InheritPhaseShift(creature, chr); creature.SaveToDB(map.GetId(), new List <Difficulty>() { map.GetDifficultyID() }); ulong dbGuid = creature.GetSpawnId(); // current "wpCreature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior creature.CleanupsBeforeDelete(); creature.Dispose(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); creature = Creature.CreateCreatureFromDB(dbGuid, map, true, true); if (!creature) { handler.SendSysMessage(CypherStrings.WaypointVpNotcreated, 1); return(false); } stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_WAYPOINT_DATA_POSITION); stmt.AddValue(0, chr.GetPositionX()); stmt.AddValue(1, chr.GetPositionY()); stmt.AddValue(2, chr.GetPositionZ()); stmt.AddValue(3, pathid); stmt.AddValue(4, point); DB.World.Execute(stmt); handler.SendSysMessage(CypherStrings.WaypointChanged); return(true); } // move if (string.IsNullOrEmpty(arg_str)) { // show_str check for present in list of correct values, no sql injection possible DB.World.Execute("UPDATE waypoint_data SET {0}=null WHERE id='{1}' AND point='{2}'", show, pathid, point); // Query can't be a prepared statement } else { // show_str check for present in list of correct values, no sql injection possible DB.World.Execute("UPDATE waypoint_data SET {0}='{1}' WHERE id='{2}' AND point='{3}'", show, arg_str, pathid, point); // Query can't be a prepared statement } handler.SendSysMessage(CypherStrings.WaypointChangedNo, show); return(true); }