private static void DoPlayerEnterWorld(Session session, Character character, PlayerBiotas biotas) { Player player; if (biotas.Player.WeenieType == (int)WeenieType.Admin) { player = new Admin(biotas.Player, biotas.Inventory, biotas.WieldedItems, character, session); } else if (biotas.Player.WeenieType == (int)WeenieType.Sentinel) { player = new Sentinel(biotas.Player, biotas.Inventory, biotas.WieldedItems, character, session); } else { player = new Player(biotas.Player, biotas.Inventory, biotas.WieldedItems, character, session); } session.SetPlayer(player); session.Player.PlayerEnterWorld(); if (character.TotalLogins <= 1 || PropertyManager.GetBool("alwaysshowwelcome").Item) { // check the value of the welcome message. Only display it if it is not empty string welcomeHeader = ConfigManager.Config.Server.Welcome ?? "Welcome to Asheron's Call!"; string msg = "To begin your training, speak to the Society Greeter. Walk up to the Society Greeter using the 'W' key, then double-click on her to initiate a conversation."; session.Network.EnqueueSend(new GameEventPopupString(session, $"{welcomeHeader}\n{msg}")); } LandblockManager.AddObject(session.Player, true); var motdString = PropertyManager.GetString("motd_string").Item; session.Network.EnqueueSend(new GameMessageSystemChat(motdString, ChatMessageType.Broadcast)); }
private static void DoPlayerEnterWorld(Session session, Character character, Biota playerBiota, PossessedBiotas possessedBiotas) { Player player; Player.HandleNoLogLandblock(playerBiota); if (playerBiota.WeenieType == (int)WeenieType.Admin) { player = new Admin(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } else if (playerBiota.WeenieType == (int)WeenieType.Sentinel) { player = new Sentinel(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } else { player = new Player(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } session.SetPlayer(player); // If the client is missing a location, we start them off in the starter dungeon if (session.Player.Location == null) { if (session.Player.Instantiation != null) { session.Player.Location = new Position(session.Player.Instantiation); } else { session.Player.Location = new Position(2349072813, 12.3199f, -28.482f, 0.0049999995f, 0.0f, 0.0f, -0.9408059f, -0.3389459f); } } session.Player.PlayerEnterWorld(); if (character.TotalLogins <= 1 || PropertyManager.GetBool("alwaysshowwelcome").Item) { // check the value of the welcome message. Only display it if it is not empty string welcomeHeader = !string.IsNullOrEmpty(ConfigManager.Config.Server.Welcome) ? ConfigManager.Config.Server.Welcome : "Welcome to Asheron's Call!"; string msg = "To begin your training, speak to the Society Greeter. Walk up to the Society Greeter using the 'W' key, then double-click on her to initiate a conversation."; session.Network.EnqueueSend(new GameEventPopupString(session, $"{welcomeHeader}\n{msg}")); } LandblockManager.AddObject(session.Player, true); var motdString = PropertyManager.GetString("motd_string").Item; session.Network.EnqueueSend(new GameMessageSystemChat(motdString, ChatMessageType.Broadcast)); }
public static void PlayerEnterWorld(Session session, Character character) { var start = DateTime.UtcNow; DatabaseManager.Shard.GetPlayerBiotas(character.Id, biotas => { log.Info("GetPlayerBiotas took " + (DateTime.UtcNow - start).TotalMilliseconds + " ms"); // This can be removed after EF performance is at the desired level. Player player; if (biotas.Player.WeenieType == (int)WeenieType.Admin) { player = new Admin(biotas.Player, biotas.Inventory, biotas.WieldedItems, character, session); } else if (biotas.Player.WeenieType == (int)WeenieType.Sentinel) { player = new Sentinel(biotas.Player, biotas.Inventory, biotas.WieldedItems, character, session); } else { player = new Player(biotas.Player, biotas.Inventory, biotas.WieldedItems, character, session); } session.SetPlayer(player); session.Player.PlayerEnterWorld(); // check the value of the welcome message. Only display it if it is not empty string welcomeHeader; if (!String.IsNullOrEmpty(ConfigManager.Config.Server.Welcome)) { welcomeHeader = ConfigManager.Config.Server.Welcome; } else { welcomeHeader = "Welcome to Asheron's Call!"; } string msg = "To begin your training, speak to the Society Greeter. Walk up to the Society Greeter using the 'W' key, then double-click on her to initiate a conversation."; if ((player.TotalLogins <= 1) || ((bool)PropertyManager.GetBool("alwaysshowwelcome").Item == true)) { session.Network.EnqueueSend(new GameEventPopupString(session, $"{welcomeHeader}\n{msg}")); } var location = player.GetPosition(PositionType.Location); var landblock = GetLandblock(location.LandblockId, true); landblock.AddWorldObject(session.Player); session.Network.EnqueueSend(new GameMessageSystemChat(MotdString, ChatMessageType.Broadcast)); }); }
/// <summary> /// Returns TRUE if a player currently meets all of the requirements for owning their house (allegiance rank) /// </summary> private static bool HasRequirements(PlayerHouse playerHouse) { if (!PropertyManager.GetBool("house_purchase_requirements").Item) { return(true); } var slumlord = playerHouse.House.SlumLord; if (slumlord.AllegianceMinLevel == null) { return(true); } var allegianceMinLevel = PropertyManager.GetLong("mansion_min_rank", -1).Item; if (allegianceMinLevel == -1) { allegianceMinLevel = slumlord.AllegianceMinLevel.Value; } var player = PlayerManager.FindByGuid(playerHouse.PlayerGuid); if (player == null) { log.Info($"{playerHouse.PlayerName}.HasRequirements() - couldn't find player"); return(false); } // ensure allegiance is loaded var allegiance = AllegianceManager.GetAllegiance(player); AllegianceNode allegianceNode = null; if (allegiance != null) { allegiance.Members.TryGetValue(player.Guid, out allegianceNode); } var rank = allegianceNode != null ? allegianceNode.Rank : 0; if (allegiance == null || rank < allegianceMinLevel) { log.Info($"{playerHouse.PlayerName}.HasRequirements() - allegiance rank {rank} < {allegianceMinLevel}"); return(false); } return(true); }
public static bool IsEventStarted(string e) { if (e.Equals("EventIsPKWorld", StringComparison.OrdinalIgnoreCase)) // special event { var serverPkState = PropertyManager.GetBool("pk_server").Item; return(serverPkState); } if (!Events.TryGetValue(e, out Event evnt)) { return(false); } return(evnt.State == (int)GameEventState.On); }
public static void BroadcastToAuditChannel(Player issuer, string message) { if (issuer != null) { BroadcastToChannel(Channel.Audit, issuer, message, true, true); } else { BroadcastToChannelFromConsole(Channel.Audit, message); } if (PropertyManager.GetBool("log_audit", true).Item) { log.Info($"[AUDIT] {(issuer != null ? $"{issuer.Name} says on the Audit channel: " : "")}{message}"); } }
public static void Initialize() { var thread = new Thread(() => { LandblockManager.PreloadConfigLandblocks(); UpdateWorld(); }); thread.Name = "World Manager"; thread.Start(); log.DebugFormat("ServerTime initialized to {0}", Timers.WorldStartLoreTime); log.DebugFormat($"Current maximum allowed sessions: {ConfigManager.Config.Server.Network.MaximumAllowedSessions}"); log.Info($"World started and is currently {WorldStatus.ToString()}{(PropertyManager.GetBool("world_closed", false).Item ? "" : " and will open automatically when server startup is complete.")}"); if (WorldStatus == WorldStatusState.Closed) { log.Info($"To open world to players, use command: world open"); } }
public static GameEventState GetEventStatus(string e) { if (e.Equals("EventIsPKWorld", StringComparison.OrdinalIgnoreCase)) // special event { if (PropertyManager.GetBool("pk_server").Item) { return(GameEventState.On); } else { return(GameEventState.Off); } } if (!Events.TryGetValue(e, out Event evnt)) { return(GameEventState.Undef); } return((GameEventState)evnt.State); }
public static bool HasRequirements(PlayerHouse playerHouse) { if (!PropertyManager.GetBool("house_purchase_requirements").Item) { return(true); } var slumlord = playerHouse.House.SlumLord; if (slumlord.AllegianceMinLevel == null) { return(true); } var allegianceMinLevel = PropertyManager.GetLong("mansion_min_rank", -1).Item; if (allegianceMinLevel == -1) { allegianceMinLevel = slumlord.AllegianceMinLevel.Value; } var player = PlayerManager.FindByGuid(playerHouse.PlayerGuid); if (player == null) { log.Info($"{playerHouse.PlayerName}.HasRequirements() - couldn't find player"); return(false); } if (player.Allegiance == null || player.AllegianceNode.Rank < allegianceMinLevel) { log.Info($"{playerHouse.PlayerName}.HasRequirements() - allegiance rank {player.AllegianceNode.Rank} < {allegianceMinLevel}"); return(false); } return(true); }
/// <summary> /// Handles the eviction process for a player house /// </summary> public static void HandleEviction(House house, uint playerGuid, bool multihouse = false, bool force = false) { // clear out slumlord inventory var slumlord = house.SlumLord; slumlord.ClearInventory(); var player = PlayerManager.FindByGuid(playerGuid, out bool isOnline); if (!PropertyManager.GetBool("house_rent_enabled", true).Item&& !multihouse && !force) { // rent disabled, push forward var purchaseTime = (uint)(player.HousePurchaseTimestamp ?? 0); var nextRentTime = house.GetRentDue(purchaseTime); player.HouseRentTimestamp = (int)nextRentTime; log.Debug($"[HOUSE] HouseManager.HandleRentPaid({player.Name}): house rent disabled via config"); // re-add item to queue AddRentQueue(player, house); return; } // handle eviction house.HouseOwner = null; house.MonarchId = null; house.HouseOwnerName = null; house.ClearPermissions(); house.SaveBiotaToDatabase(); // relink house.UpdateLinks(); if (house.HasDungeon) { var dungeonHouse = house.GetDungeonHouse(); if (dungeonHouse != null) { dungeonHouse.UpdateLinks(); } } // player slumlord 'off' animation slumlord.Off(); // reset slumlord name slumlord.SetAndBroadcastName(); slumlord.SaveBiotaToDatabase(); // if evicting a multihouse owner's previous house, // no update for player properties if (player.HouseInstance == house.Guid.Full) { player.HouseId = null; player.HouseInstance = null; //player.HousePurchaseTimestamp = null; player.HouseRentTimestamp = null; } else { log.Warn($"[HOUSE] HouseManager.HandleRentEviction({house.Guid}, {player.Name}, {multihouse}): house guids don't match {player.HouseInstance}"); } house.ClearRestrictions(); log.Debug($"[HOUSE] HouseManager.HandleRentEviction({player.Name})"); if (multihouse) { RemoveRentQueue(house.Guid.Full); player.SaveBiotaToDatabase(); return; } if (!isOnline) { // inform player of eviction when they log in var offlinePlayer = PlayerManager.GetOfflinePlayer(playerGuid); if (offlinePlayer == null) { log.Warn($"[HOUSE] {player.Name}.HandleEviction(): couldn't find offline player"); return; } offlinePlayer.SetProperty(PropertyBool.HouseEvicted, true); offlinePlayer.SaveBiotaToDatabase(); return; } var onlinePlayer = PlayerManager.GetOnlinePlayer(playerGuid); onlinePlayer.House = null; // send text message onlinePlayer.Session.Network.EnqueueSend(new GameMessageSystemChat("Your house has reverted due to non-payment of the maintenance costs. All items stored in the house have been lost.", ChatMessageType.Broadcast)); onlinePlayer.RemoveDeed(); onlinePlayer.SaveBiotaToDatabase(); // clear house panel for online player var actionChain = new ActionChain(); actionChain.AddDelaySeconds(3.0f); // wait for slumlord inventory biotas above to save actionChain.AddAction(onlinePlayer, onlinePlayer.HandleActionQueryHouse); actionChain.EnqueueChain(); }
/// <summary> /// Queries the status of multi-house owners on the server /// </summary> private static void QueryMultiHouse() { var slumlordBiotas = DatabaseManager.Shard.BaseDatabase.GetBiotasByType(WeenieType.SlumLord); var playerHouses = new Dictionary <IPlayer, List <Biota> >(); var accountHouses = new Dictionary <string, List <Biota> >(); foreach (var slumlord in slumlordBiotas) { var biotaOwner = slumlord.BiotaPropertiesIID.FirstOrDefault(i => i.Type == (ushort)PropertyInstanceId.HouseOwner); if (biotaOwner == null) { // this is fine. this is just a house that was purchased, and then later abandoned //Console.WriteLine($"HouseManager.QueryMultiHouse(): couldn't find owner for house {slumlord.Id:X8}"); continue; } var owner = PlayerManager.FindByGuid(biotaOwner.Value); if (owner == null) { Console.WriteLine($"HouseManager.QueryMultiHouse(): couldn't find owner {biotaOwner.Value:X8}"); continue; } if (!playerHouses.TryGetValue(owner, out var houses)) { houses = new List <Biota>(); playerHouses.Add(owner, houses); } houses.Add(slumlord); var accountName = owner.Account != null ? owner.Account.AccountName : "NULL"; if (!accountHouses.TryGetValue(accountName, out var aHouses)) { aHouses = new List <Biota>(); accountHouses.Add(accountName, aHouses); } aHouses.Add(slumlord); } if (PropertyManager.GetBool("house_per_char").Item) { var results = playerHouses.Where(i => i.Value.Count() > 1).OrderByDescending(i => i.Value.Count()); if (results.Count() > 0) { Console.WriteLine("Multi-house owners:"); } foreach (var playerHouse in results) { Console.WriteLine($"{playerHouse.Key.Name}: {playerHouse.Value.Count}"); for (var i = 0; i < playerHouse.Value.Count; i++) { Console.WriteLine($"{i + 1}. {GetCoords(playerHouse.Value[i])}"); } } } else { var results = accountHouses.Where(i => i.Value.Count() > 1).OrderByDescending(i => i.Value.Count()); if (results.Count() > 0) { Console.WriteLine("Multi-house owners:"); } foreach (var accountHouse in results) { Console.WriteLine($"{accountHouse.Key}: {accountHouse.Value.Count}"); for (var i = 0; i < accountHouse.Value.Count; i++) { Console.WriteLine($"{i + 1}. {GetCoords(accountHouse.Value[i])}"); } } } }
/// <summary> /// Increments the counter for a kill task, and optionally shares with fellowship /// </summary> public void HandleKillTask(string killQuestName, WorldObject killedCreature, bool shareable = true) { var player = Creature as Player; if (player == null) { return; } // http://acpedia.org/wiki/Announcements_-_2012/12_-_A_Growing_Twilight#Release_Notes if (killedCreature == null) { log.Error($"{Name}.QuestManager.HandleKillTask({killQuestName}): input object is null!"); return; } var questName = GetQuestName(killQuestName); var quest = DatabaseManager.World.GetCachedQuest(questName); if (quest == null) { log.Error($"{Name}.QuestManager.HandleKillTask({killQuestName}): couldn't find kill task {questName} in database"); return; } if (HasQuest(questName)) { Stamp(killQuestName); var playerQuest = Quests.FirstOrDefault(q => q.QuestName.Equals(questName, StringComparison.OrdinalIgnoreCase)); if (playerQuest == null) { // this should be impossible log.Error($"{Name}.QuestManager.HandleKillTask({killQuestName}): couldn't find kill task {questName} in player quests"); return; } var msg = $"You have killed {playerQuest.NumTimesCompleted} {killedCreature.GetPluralName()}!"; if (IsMaxSolves(questName)) { msg += $" Your task is complete."; } else { msg += $" You must kill {quest.MaxSolves} to complete your task."; } player.Session.Network.EnqueueSend(new GameMessageSystemChat(msg, ChatMessageType.Broadcast)); } else if (PropertyManager.GetBool("fellow_kt_killer").Item) { // if this option is enabled (retail default), the killer is required to have kill task // for it to share with fellowship return; } // is player in fellowship? if (player.Fellowship != null && shareable) { // if so, share with fellows within range var fellows = player.Fellowship.WithinRange(player); foreach (var fellow in fellows) { fellow.QuestManager.HandleKillTask(killQuestName, killedCreature, false); } } }
private static void DoPlayerEnterWorld(Session session, Character character, Biota playerBiota, PossessedBiotas possessedBiotas) { Player player; Player.HandleNoLogLandblock(playerBiota, out var playerLoggedInOnNoLogLandblock); var stripAdminProperties = false; var addAdminProperties = false; var addSentinelProperties = false; if (ConfigManager.Config.Server.Accounts.OverrideCharacterPermissions) { if (session.AccessLevel <= AccessLevel.Advocate) // check for elevated characters { if (playerBiota.WeenieType == WeenieType.Admin || playerBiota.WeenieType == WeenieType.Sentinel) // Downgrade weenie { character.IsPlussed = false; playerBiota.WeenieType = WeenieType.Creature; stripAdminProperties = true; } } else if (session.AccessLevel >= AccessLevel.Sentinel && session.AccessLevel <= AccessLevel.Envoy) { if (playerBiota.WeenieType == WeenieType.Creature || playerBiota.WeenieType == WeenieType.Admin) // Up/downgrade weenie { character.IsPlussed = true; playerBiota.WeenieType = WeenieType.Sentinel; addSentinelProperties = true; } } else // Developers and Admins { if (playerBiota.WeenieType == WeenieType.Creature || playerBiota.WeenieType == WeenieType.Sentinel) // Up/downgrade weenie { character.IsPlussed = true; playerBiota.WeenieType = WeenieType.Admin; addAdminProperties = true; } } } if (playerBiota.WeenieType == WeenieType.Admin) { player = new Admin(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } else if (playerBiota.WeenieType == WeenieType.Sentinel) { player = new Sentinel(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } else { player = new Player(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } session.SetPlayer(player); if (stripAdminProperties) // continue stripping properties { player.CloakStatus = CloakStatus.Undef; player.Attackable = true; player.SetProperty(PropertyBool.DamagedByCollisions, true); player.AdvocateLevel = null; player.ChannelsActive = null; player.ChannelsAllowed = null; player.Invincible = false; player.Cloaked = null; player.IgnoreHouseBarriers = false; player.IgnorePortalRestrictions = false; player.SafeSpellComponents = false; player.ReportCollisions = true; player.ChangesDetected = true; player.CharacterChangesDetected = true; } if (addSentinelProperties || addAdminProperties) // continue restoring properties to default { WorldObject weenie; if (addAdminProperties) { weenie = Factories.WorldObjectFactory.CreateWorldObject(DatabaseManager.World.GetCachedWeenie("admin"), new ACE.Entity.ObjectGuid(ACE.Entity.ObjectGuid.Invalid.Full)); } else { weenie = Factories.WorldObjectFactory.CreateWorldObject(DatabaseManager.World.GetCachedWeenie("sentinel"), new ACE.Entity.ObjectGuid(ACE.Entity.ObjectGuid.Invalid.Full)); } if (weenie != null) { player.CloakStatus = CloakStatus.Off; player.Attackable = weenie.Attackable; player.SetProperty(PropertyBool.DamagedByCollisions, false); player.AdvocateLevel = weenie.GetProperty(PropertyInt.AdvocateLevel); player.ChannelsActive = (Channel?)weenie.GetProperty(PropertyInt.ChannelsActive); player.ChannelsAllowed = (Channel?)weenie.GetProperty(PropertyInt.ChannelsAllowed); player.Invincible = false; player.Cloaked = false; player.ChangesDetected = true; player.CharacterChangesDetected = true; } } // If the client is missing a location, we start them off in the starter town they chose if (session.Player.Location == null) { if (session.Player.Instantiation != null) { session.Player.Location = new Position(session.Player.Instantiation); } else { session.Player.Location = new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f); // ultimate fallback } } var olthoiPlayerReturnedToLifestone = session.Player.IsOlthoiPlayer && character.TotalLogins >= 1 && session.Player.LoginAtLifestone; if (olthoiPlayerReturnedToLifestone) { session.Player.Location = new Position(session.Player.Sanctuary); } session.Player.PlayerEnterWorld(); var success = LandblockManager.AddObject(session.Player, true); if (!success) { // send to lifestone, or fallback location var fixLoc = session.Player.Sanctuary ?? new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f); log.Error($"WorldManager.DoPlayerEnterWorld: failed to spawn {session.Player.Name}, relocating to {fixLoc.ToLOCString()}"); session.Player.Location = new Position(fixLoc); LandblockManager.AddObject(session.Player, true); var actionChain = new ActionChain(); actionChain.AddDelaySeconds(5.0f); actionChain.AddAction(session.Player, () => { if (session != null && session.Player != null) { session.Player.Teleport(fixLoc); } }); actionChain.EnqueueChain(); } // These warnings are set by DDD_InterrogationResponse if ((session.DatWarnCell || session.DatWarnLanguage || session.DatWarnPortal) && PropertyManager.GetBool("show_dat_warning").Item) { var msg = PropertyManager.GetString("dat_warning_msg").Item; var chatMsg = new GameMessageSystemChat(msg, ChatMessageType.System); session.Network.EnqueueSend(chatMsg); } var popup_header = PropertyManager.GetString("popup_header").Item; var popup_motd = PropertyManager.GetString("popup_motd").Item; var popup_welcome = player.IsOlthoiPlayer ? PropertyManager.GetString("popup_welcome_olthoi").Item : PropertyManager.GetString("popup_welcome").Item; if (character.TotalLogins <= 1) { if (player.IsOlthoiPlayer) { session.Network.EnqueueSend(new GameEventPopupString(session, AppendLines(popup_welcome, popup_motd))); } else { session.Network.EnqueueSend(new GameEventPopupString(session, AppendLines(popup_header, popup_motd, popup_welcome))); } } else if (!string.IsNullOrEmpty(popup_motd)) { session.Network.EnqueueSend(new GameEventPopupString(session, AppendLines(popup_header, popup_motd))); } var info = "Welcome to Asheron's Call\n powered by ACEmulator\n\nFor more information on commands supported by this server, type @acehelp\n"; session.Network.EnqueueSend(new GameMessageSystemChat(info, ChatMessageType.Broadcast)); var server_motd = PropertyManager.GetString("server_motd").Item; if (!string.IsNullOrEmpty(server_motd)) { session.Network.EnqueueSend(new GameMessageSystemChat($"{server_motd}\n", ChatMessageType.Broadcast)); } if (olthoiPlayerReturnedToLifestone) { session.Network.EnqueueSend(new GameMessageSystemChat("You have returned to the Olthoi Queen to serve the hive.", ChatMessageType.Broadcast)); } else if (playerLoggedInOnNoLogLandblock) // see http://acpedia.org/wiki/Mount_Elyrii_Hive { session.Network.EnqueueSend(new GameMessageSystemChat("The currents of portal space cannot return you from whence you came. Your previous location forbids login.", ChatMessageType.Broadcast)); } }
public static void LogBroadcastChat(Channel channel, WorldObject sender, string message) { switch (channel) { case Channel.Abuse: if (!PropertyManager.GetBool("chat_log_abuse").Item) { return; } break; case Channel.Admin: if (!PropertyManager.GetBool("chat_log_admin").Item) { return; } break; case Channel.AllBroadcast: // using this to sub in for a WorldBroadcast channel which isn't technically a channel if (!PropertyManager.GetBool("chat_log_global").Item) { return; } break; case Channel.Audit: if (!PropertyManager.GetBool("chat_log_audit").Item) { return; } break; case Channel.Advocate1: case Channel.Advocate2: case Channel.Advocate3: if (!PropertyManager.GetBool("chat_log_advocate").Item) { return; } break; case Channel.Debug: if (!PropertyManager.GetBool("chat_log_debug").Item) { return; } break; case Channel.Fellow: case Channel.FellowBroadcast: if (!PropertyManager.GetBool("chat_log_fellow").Item) { return; } break; case Channel.Help: if (!PropertyManager.GetBool("chat_log_help").Item) { return; } break; case Channel.Olthoi: if (!PropertyManager.GetBool("chat_log_olthoi").Item) { return; } break; case Channel.QA1: case Channel.QA2: if (!PropertyManager.GetBool("chat_log_qa").Item) { return; } break; case Channel.Sentinel: if (!PropertyManager.GetBool("chat_log_sentinel").Item) { return; } break; case Channel.SocietyCelHanBroadcast: case Channel.SocietyEldWebBroadcast: case Channel.SocietyRadBloBroadcast: if (!PropertyManager.GetBool("chat_log_society").Item) { return; } break; case Channel.AllegianceBroadcast: case Channel.CoVassals: case Channel.Monarch: case Channel.Patron: case Channel.Vassals: if (!PropertyManager.GetBool("chat_log_allegiance").Item) { return; } break; case Channel.AlArqas: case Channel.Holtburg: case Channel.Lytelthorpe: case Channel.Nanto: case Channel.Rithwic: case Channel.Samsur: case Channel.Shoushi: case Channel.Yanshi: case Channel.Yaraq: if (!PropertyManager.GetBool("chat_log_townchans").Item) { return; } break; default: return; } if (channel != Channel.AllBroadcast) { log.Info($"[CHAT][{channel.ToString().ToUpper()}] {(sender != null ? sender.Name : "[SYSTEM]")} says on the {channel} channel, \"{message}\""); } else { log.Info($"[CHAT][GLOBAL] {(sender != null ? sender.Name : "[SYSTEM]")} issued a world broadcast, \"{message}\""); } }
/// <summary> /// Handles the eviction process for a player house /// </summary> public static void HandleEviction(House house, uint playerGuid, bool multihouse = false) { // clear out slumlord inventory var slumlord = house.SlumLord; slumlord.ClearInventory(true); var player = PlayerManager.FindByGuid(playerGuid, out bool isOnline); if (!PropertyManager.GetBool("house_rent_enabled", true).Item&& !multihouse) { // rent disabled, push forward var purchaseTime = (uint)(player.HousePurchaseTimestamp ?? 0); var nextRentTime = house.GetRentDue(purchaseTime); player.HouseRentTimestamp = (int)nextRentTime; log.Info($"HouseManager.HandleRentPaid({player.Name}): house rent disabled via config"); // re-add item to queue AddRentQueue(player, house); return; } // handle eviction house.HouseOwner = null; house.MonarchId = null; house.HouseOwnerName = null; house.ClearPermissions(); house.SaveBiotaToDatabase(); // relink house.UpdateLinks(); // player slumlord 'off' animation var off = new Motion(MotionStance.Invalid, MotionCommand.Off); slumlord.CurrentMotionState = off; slumlord.EnqueueBroadcastMotion(off); // reset slumlord name var weenie = DatabaseManager.World.GetCachedWeenie(slumlord.WeenieClassId); var wo = WorldObjectFactory.CreateWorldObject(weenie, ObjectGuid.Invalid); slumlord.Name = wo.Name; slumlord.EnqueueBroadcast(new GameMessagePublicUpdatePropertyString(slumlord, PropertyString.Name, wo.Name)); slumlord.SaveBiotaToDatabase(); // if evicting a multihouse owner's previous house, // no update for player properties if (player.HouseInstance == house.Guid.Full) { player.HouseId = null; player.HouseInstance = null; //player.HousePurchaseTimestamp = null; player.HouseRentTimestamp = null; } else { log.Warn($"HouseManager.HandleRentEviction({house.Guid}, {player.Name}, {multihouse}): house guids don't match {player.HouseInstance}"); } house.ClearRestrictions(); log.Info($"HouseManager.HandleRentEviction({player.Name})"); if (multihouse) { RemoveRentQueue(house.Guid.Full); player.SaveBiotaToDatabase(); return; } if (!isOnline) { // inform player of eviction when they log in var offlinePlayer = PlayerManager.GetOfflinePlayer(playerGuid); if (offlinePlayer == null) { log.Warn($"{player.Name}.HandleEviction(): couldn't find offline player"); return; } offlinePlayer.SetProperty(PropertyBool.HouseEvicted, true); offlinePlayer.SaveBiotaToDatabase(); return; } var onlinePlayer = PlayerManager.GetOnlinePlayer(playerGuid); onlinePlayer.House = null; // send text message onlinePlayer.Session.Network.EnqueueSend(new GameMessageSystemChat("You abandon your house!", ChatMessageType.Broadcast)); onlinePlayer.RemoveDeed(); onlinePlayer.SaveBiotaToDatabase(); // clear house panel for online player var actionChain = new ActionChain(); actionChain.AddDelaySeconds(3.0f); // wait for slumlord inventory biotas above to save actionChain.AddAction(onlinePlayer, onlinePlayer.HandleActionQueryHouse); actionChain.EnqueueChain(); }
public static async void HandleEviction(PlayerHouse playerHouse) { // todo: copied from Player_House.HandleActionAbandonHouse, move to House.Abandon() // todo: get online copy of house var house = playerHouse.House; // clear out slumlord inventory // todo: get online copy of house var slumlord = house.SlumLord; slumlord.ClearInventory(true); var player = PlayerManager.FindByGuid(playerHouse.PlayerGuid, out bool isOnline); if (!PropertyManager.GetBool("house_rent_enabled", true).Item) { // rent disabled, push forward var purchaseTime = (uint)(player.HousePurchaseTimestamp ?? 0); var nextRentTime = house.GetRentDue(purchaseTime); player.HouseRentTimestamp = (int)nextRentTime; log.Info($"HouseManager.HandleRentPaid({playerHouse.PlayerName}): house rent disabled via config"); BuildRentQueue(); return; } house.HouseOwner = null; house.MonarchId = null; house.HouseOwnerName = null; house.ClearPermissions(); house.SaveBiotaToDatabase(); // relink house.UpdateLinks(); // player slumlord 'off' animation var off = new Motion(MotionStance.Invalid, MotionCommand.Off); slumlord.CurrentMotionState = off; slumlord.EnqueueBroadcastMotion(off); // reset slumlord name var weenie = DatabaseManager.World.GetCachedWeenie(slumlord.WeenieClassId); var wo = WorldObjectFactory.CreateWorldObject(weenie, ObjectGuid.Invalid); slumlord.Name = wo.Name; slumlord.EnqueueBroadcast(new GameMessagePublicUpdatePropertyString(slumlord, PropertyString.Name, wo.Name)); slumlord.SaveBiotaToDatabase(); player.HouseId = null; player.HouseInstance = null; //player.HousePurchaseTimestamp = null; player.HouseRentTimestamp = null; house.ClearRestrictions(); log.Info($"HouseManager.HandleRentEviction({playerHouse.PlayerName})"); BuildRentQueue(); if (!isOnline) { // inform player of eviction when they log in var offlinePlayer = PlayerManager.GetOfflinePlayer(playerHouse.PlayerGuid); if (offlinePlayer == null) { log.Warn($"{playerHouse.PlayerName}.HandleEviction(): couldn't find offline player"); return; } offlinePlayer.SetProperty(PropertyBool.HouseEvicted, true); offlinePlayer.SaveBiotaToDatabase(); return; } var onlinePlayer = PlayerManager.GetOnlinePlayer(playerHouse.PlayerGuid); onlinePlayer.House = null; // send text message onlinePlayer.Session.Network.EnqueueSend(new GameMessageSystemChat("You abandon your house!", ChatMessageType.Broadcast)); onlinePlayer.RemoveDeed(); await Task.Delay(3000); // wait for slumlord inventory biotas above to save onlinePlayer.HandleActionQueryHouse(); }
private static void DoPlayerEnterWorld(Session session, Character character, Biota playerBiota, PossessedBiotas possessedBiotas) { Player player; Player.HandleNoLogLandblock(playerBiota); var stripAdminProperties = false; var addAdminProperties = false; var addSentinelProperties = false; if (ConfigManager.Config.Server.Accounts.OverrideCharacterPermissions) { if (session.AccessLevel <= AccessLevel.Advocate) // check for elevated characters { if (playerBiota.WeenieType == WeenieType.Admin || playerBiota.WeenieType == WeenieType.Sentinel) // Downgrade weenie { character.IsPlussed = false; playerBiota.WeenieType = WeenieType.Creature; stripAdminProperties = true; } } else if (session.AccessLevel >= AccessLevel.Sentinel && session.AccessLevel <= AccessLevel.Envoy) { if (playerBiota.WeenieType == WeenieType.Creature || playerBiota.WeenieType == WeenieType.Admin) // Up/downgrade weenie { character.IsPlussed = true; playerBiota.WeenieType = WeenieType.Sentinel; addSentinelProperties = true; } } else // Developers and Admins { if (playerBiota.WeenieType == WeenieType.Creature || playerBiota.WeenieType == WeenieType.Sentinel) // Up/downgrade weenie { character.IsPlussed = true; playerBiota.WeenieType = WeenieType.Admin; addAdminProperties = true; } } } if (playerBiota.WeenieType == WeenieType.Admin) { player = new Admin(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } else if (playerBiota.WeenieType == WeenieType.Sentinel) { player = new Sentinel(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } else { player = new Player(playerBiota, possessedBiotas.Inventory, possessedBiotas.WieldedItems, character, session); } session.SetPlayer(player); if (stripAdminProperties) // continue stripping properties { player.CloakStatus = CloakStatus.Undef; player.Attackable = true; player.SetProperty(ACE.Entity.Enum.Properties.PropertyBool.DamagedByCollisions, true); player.AdvocateLevel = null; player.ChannelsActive = null; player.ChannelsAllowed = null; player.Invincible = false; player.Cloaked = null; player.IgnoreHouseBarriers = false; player.IgnorePortalRestrictions = false; player.SafeSpellComponents = false; player.ChangesDetected = true; player.CharacterChangesDetected = true; } if (addSentinelProperties || addAdminProperties) // continue restoring properties to default { WorldObject weenie; if (addAdminProperties) { weenie = Factories.WorldObjectFactory.CreateWorldObject(DatabaseManager.World.GetCachedWeenie("admin"), new ACE.Entity.ObjectGuid(ACE.Entity.ObjectGuid.Invalid.Full)); } else { weenie = Factories.WorldObjectFactory.CreateWorldObject(DatabaseManager.World.GetCachedWeenie("sentinel"), new ACE.Entity.ObjectGuid(ACE.Entity.ObjectGuid.Invalid.Full)); } if (weenie != null) { player.CloakStatus = CloakStatus.Off; player.Attackable = weenie.Attackable; player.SetProperty(ACE.Entity.Enum.Properties.PropertyBool.DamagedByCollisions, false); player.AdvocateLevel = weenie.GetProperty(ACE.Entity.Enum.Properties.PropertyInt.AdvocateLevel); player.ChannelsActive = (Channel?)weenie.GetProperty(ACE.Entity.Enum.Properties.PropertyInt.ChannelsActive); player.ChannelsAllowed = (Channel?)weenie.GetProperty(ACE.Entity.Enum.Properties.PropertyInt.ChannelsAllowed); player.Invincible = false; player.Cloaked = false; player.ChangesDetected = true; player.CharacterChangesDetected = true; } } // If the client is missing a location, we start them off in the starter town they chose if (session.Player.Location == null) { if (session.Player.Instantiation != null) { session.Player.Location = new Position(session.Player.Instantiation); } else { session.Player.Location = new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f, 0); // ultimate fallback } } var realm = RealmManager.GetRealm(session.Player.Location.RealmID); if (realm == null) { var homerealm = RealmManager.GetRealm(session.Player.HomeRealm); if (homerealm == null) { homerealm = RealmManager.GetRealm(0); } var pos = new Position(session.Player.Location); pos.SetToDefaultRealmInstance(homerealm.Realm.Id); log.Error($"WorldManager.DoPlayerEnterWorld: failed to find realm {session.Player.Location.RealmID}, for player {session.Player.Name}, relocating to realm {homerealm.Realm.Id}."); session.Player.Location = pos; } if (!session.Player.ValidatePlayerRealmPosition(session.Player.Location)) { var homerealm = RealmManager.GetRealm(session.Player.HomeRealm); if (homerealm == null) { homerealm = RealmManager.GetRealm(0); } var exitloc = session.Player.GetPosition(ACE.Entity.Enum.Properties.PositionType.EphemeralRealmExitTo); if (exitloc != null) { session.Network.EnqueueSend(new GameMessageSystemChat($"The instance you were in has expired and you have been transported outside!", ChatMessageType.System)); session.Player.ExitInstance(); } else { var pos = new Position(session.Player.Location); pos.SetToDefaultRealmInstance(homerealm.Realm.Id); session.Network.EnqueueSend(new GameMessageSystemChat($"You have been transported back to your home realm.", ChatMessageType.System)); log.Info($"WorldManager.DoPlayerEnterWorld: player {session.Player.Name} doesn't have permission to be in realm {session.Player.Location.RealmID}, relocating to realm {homerealm.Realm.Id}."); session.Player.Location = pos; } } session.Player.PlayerEnterWorld(); var success = LandblockManager.AddObject(session.Player, true); if (!success) { // send to lifestone, or fallback location var fixLoc = session.Player.Sanctuary ?? new Position(0xA9B40019, 84, 7.1f, 94, 0, 0, -0.0784591f, 0.996917f, 0); log.Error($"WorldManager.DoPlayerEnterWorld: failed to spawn {session.Player.Name}, relocating to {fixLoc.ToLOCString()}"); session.Player.Location = new Position(fixLoc); LandblockManager.AddObject(session.Player, true); var actionChain = new ActionChain(); actionChain.AddDelaySeconds(5.0f); actionChain.AddAction(session.Player, () => { if (session != null && session.Player != null) { session.Player.Teleport(fixLoc); } }); actionChain.EnqueueChain(); } // These warnings are set by DDD_InterrogationResponse if ((session.DatWarnCell || session.DatWarnLanguage || session.DatWarnPortal) && PropertyManager.GetBool("show_dat_warning").Item) { var msg = PropertyManager.GetString("dat_warning_msg").Item; var chatMsg = new GameMessageSystemChat(msg, ChatMessageType.System); session.Network.EnqueueSend(chatMsg); } var popup_header = PropertyManager.GetString("popup_header").Item; var popup_motd = PropertyManager.GetString("popup_motd").Item; var popup_welcome = PropertyManager.GetString("popup_welcome").Item; if (character.TotalLogins <= 1) { session.Network.EnqueueSend(new GameEventPopupString(session, AppendLines(popup_header, popup_motd, popup_welcome))); } else if (!string.IsNullOrEmpty(popup_motd)) { session.Network.EnqueueSend(new GameEventPopupString(session, AppendLines(popup_header, popup_motd))); } var info = "Welcome to Asheron's Call\n powered by ACEmulator\n\nFor more information on commands supported by this server, type @acehelp\n"; session.Network.EnqueueSend(new GameMessageSystemChat(info, ChatMessageType.Broadcast)); var server_motd = PropertyManager.GetString("server_motd").Item; if (!string.IsNullOrEmpty(server_motd)) { session.Network.EnqueueSend(new GameMessageSystemChat($"{server_motd}\n", ChatMessageType.Broadcast)); } }
public static void UpdatePKStatusForAllPlayers(string worldType, bool enabled) { switch (worldType) { case "pk_server": if (enabled) { foreach (var player in GetAllOnline()) { player.SetPlayerKillerStatus(PlayerKillerStatus.PK, true); } foreach (var player in GetAllOffline()) { player.SetProperty(PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.NPK); player.SetProperty(PropertyFloat.MinimumTimeSincePk, 0); } BroadcastToAll(new GameMessageSystemChat($"This world has been changed to a Player Killer world. All players will become Player Killers in {PropertyManager.GetDouble("pk_respite_timer").Item} seconds.", ChatMessageType.WorldBroadcast)); } else { foreach (var player in GetAllOnline()) { player.SetPlayerKillerStatus(PlayerKillerStatus.NPK, true); } foreach (var player in GetAllOffline()) { player.SetProperty(PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.NPK); player.SetProperty(PropertyFloat.MinimumTimeSincePk, 0); } BroadcastToAll(new GameMessageSystemChat("This world has been changed to a Non Player Killer world. All players are now Non-Player Killers.", ChatMessageType.WorldBroadcast)); } break; case "pkl_server": if (PropertyManager.GetBool("pk_server").Item) { return; } if (enabled) { foreach (var player in GetAllOnline()) { player.SetPlayerKillerStatus(PlayerKillerStatus.PKLite, true); } foreach (var player in GetAllOffline()) { player.SetProperty(PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.NPK); player.SetProperty(PropertyFloat.MinimumTimeSincePk, 0); } BroadcastToAll(new GameMessageSystemChat($"This world has been changed to a Player Killer Lite world. All players will become Player Killer Lites in {PropertyManager.GetDouble("pk_respite_timer").Item} seconds.", ChatMessageType.WorldBroadcast)); } else { foreach (var player in GetAllOnline()) { player.SetPlayerKillerStatus(PlayerKillerStatus.NPK, true); } foreach (var player in GetAllOffline()) { player.SetProperty(PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.NPK); player.SetProperty(PropertyFloat.MinimumTimeSincePk, 0); } BroadcastToAll(new GameMessageSystemChat("This world has been changed to a Non Player Killer world. All players are now Non-Player Killers.", ChatMessageType.WorldBroadcast)); } break; } }