mirror of
https://github.com/ACEmulator/ACE
synced 2026-08-17 12:26:06 -04:00
527 lines
25 KiB
C#
527 lines
25 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using log4net;
|
|
|
|
using ACE.Common;
|
|
using ACE.Database;
|
|
using ACE.Entity;
|
|
using ACE.Entity.Enum;
|
|
using ACE.Server.Entity;
|
|
using ACE.Server.Entity.Actions;
|
|
using ACE.Server.Managers;
|
|
using ACE.Server.Network;
|
|
using ACE.Server.Network.GameEvent.Events;
|
|
using ACE.Server.Network.GameMessages.Messages;
|
|
using ACE.Server.WorldObjects;
|
|
|
|
|
|
namespace ACE.Server.Command.Handlers
|
|
{
|
|
public static class PlayerCommands
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
// pop
|
|
[CommandHandler("pop", AccessLevel.Player, CommandHandlerFlag.None, 0,
|
|
"Show current world population",
|
|
"")]
|
|
public static void HandlePop(Session session, params string[] parameters)
|
|
{
|
|
CommandHandlerHelper.WriteOutputInfo(session, $"Current world population: {PlayerManager.GetOnlineCount():N0}", ChatMessageType.Broadcast);
|
|
}
|
|
|
|
// quest info (uses GDLe formatting to match plugin expectations)
|
|
[CommandHandler("myquests", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, "Shows your quest log")]
|
|
public static void HandleQuests(Session session, params string[] parameters)
|
|
{
|
|
if (!PropertyManager.GetBool("quest_info_enabled").Item)
|
|
{
|
|
session.Network.EnqueueSend(new GameMessageSystemChat("The command \"myquests\" is not currently enabled on this server.", ChatMessageType.Broadcast));
|
|
return;
|
|
}
|
|
|
|
var quests = session.Player.QuestManager.GetQuests();
|
|
|
|
if (quests.Count == 0)
|
|
{
|
|
session.Network.EnqueueSend(new GameMessageSystemChat("Quest list is empty.", ChatMessageType.Broadcast));
|
|
return;
|
|
}
|
|
|
|
foreach (var playerQuest in quests)
|
|
{
|
|
var text = "";
|
|
var questName = QuestManager.GetQuestName(playerQuest.QuestName);
|
|
var quest = DatabaseManager.World.GetCachedQuest(questName);
|
|
if (quest == null)
|
|
{
|
|
//Console.WriteLine($"Couldn't find quest {playerQuest.QuestName}");
|
|
continue;
|
|
}
|
|
|
|
var minDelta = quest.MinDelta;
|
|
if (QuestManager.CanScaleQuestMinDelta(quest))
|
|
minDelta = (uint)(quest.MinDelta * PropertyManager.GetDouble("quest_mindelta_rate").Item);
|
|
|
|
text += $"{playerQuest.QuestName.ToLower()} - {playerQuest.NumTimesCompleted} solves ({playerQuest.LastTimeCompleted})";
|
|
text += $"\"{quest.Message}\" {quest.MaxSolves} {minDelta}";
|
|
|
|
session.Network.EnqueueSend(new GameMessageSystemChat(text, ChatMessageType.Broadcast));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// For characters/accounts who currently own multiple houses, used to select which house they want to keep
|
|
/// </summary>
|
|
[CommandHandler("house-select", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, 1, "For characters/accounts who currently own multiple houses, used to select which house they want to keep")]
|
|
public static void HandleHouseSelect(Session session, params string[] parameters)
|
|
{
|
|
HandleHouseSelect(session, false, parameters);
|
|
}
|
|
|
|
public static void HandleHouseSelect(Session session, bool confirmed, params string[] parameters)
|
|
{
|
|
if (!int.TryParse(parameters[0], out var houseIdx))
|
|
return;
|
|
|
|
// ensure current multihouse owner
|
|
if (!session.Player.IsMultiHouseOwner(false))
|
|
{
|
|
log.Warn($"{session.Player.Name} tried to /house-select {houseIdx}, but they are not currently a multi-house owner!");
|
|
return;
|
|
}
|
|
|
|
// get house info for this index
|
|
var multihouses = session.Player.GetMultiHouses();
|
|
|
|
if (houseIdx < 1 || houseIdx > multihouses.Count)
|
|
{
|
|
session.Network.EnqueueSend(new GameMessageSystemChat($"Please enter a number between 1 and {multihouses.Count}.", ChatMessageType.Broadcast));
|
|
return;
|
|
}
|
|
|
|
var keepHouse = multihouses[houseIdx - 1];
|
|
|
|
// show confirmation popup
|
|
if (!confirmed)
|
|
{
|
|
var houseType = $"{keepHouse.HouseType}".ToLower();
|
|
var loc = HouseManager.GetCoords(keepHouse.SlumLord.Location);
|
|
|
|
var msg = $"Are you sure you want to keep the {houseType} at\n{loc}?";
|
|
if (!session.Player.ConfirmationManager.EnqueueSend(new Confirmation_Custom(session.Player.Guid, () => HandleHouseSelect(session, true, parameters)), msg))
|
|
session.Player.SendWeenieError(WeenieError.ConfirmationInProgress);
|
|
return;
|
|
}
|
|
|
|
// house to keep confirmed, abandon the other houses
|
|
var abandonHouses = new List<House>(multihouses);
|
|
abandonHouses.RemoveAt(houseIdx - 1);
|
|
|
|
foreach (var abandonHouse in abandonHouses)
|
|
{
|
|
var house = session.Player.GetHouse(abandonHouse.Guid.Full);
|
|
|
|
HouseManager.HandleEviction(house, house.HouseOwner ?? 0, true);
|
|
}
|
|
|
|
// set player properties for house to keep
|
|
var player = PlayerManager.FindByGuid(keepHouse.HouseOwner ?? 0, out bool isOnline);
|
|
if (player == null)
|
|
{
|
|
log.Error($"{session.Player.Name}.HandleHouseSelect({houseIdx}) - couldn't find HouseOwner {keepHouse.HouseOwner} for {keepHouse.Name} ({keepHouse.Guid})");
|
|
return;
|
|
}
|
|
|
|
player.HouseId = keepHouse.HouseId;
|
|
player.HouseInstance = keepHouse.Guid.Full;
|
|
|
|
player.SaveBiotaToDatabase();
|
|
|
|
// update house panel for current player
|
|
var actionChain = new ActionChain();
|
|
actionChain.AddDelaySeconds(3.0f); // wait for slumlord inventory biotas above to save
|
|
actionChain.AddAction(session.Player, session.Player.HandleActionQueryHouse);
|
|
actionChain.EnqueueChain();
|
|
|
|
Console.WriteLine("OK");
|
|
}
|
|
|
|
[CommandHandler("debugcast", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, "Shows debug information about the current magic casting state")]
|
|
public static void HandleDebugCast(Session session, params string[] parameters)
|
|
{
|
|
var physicsObj = session.Player.PhysicsObj;
|
|
|
|
var pendingActions = physicsObj.MovementManager.MoveToManager.PendingActions;
|
|
var currAnim = physicsObj.PartArray.Sequence.CurrAnim;
|
|
|
|
session.Network.EnqueueSend(new GameMessageSystemChat(session.Player.MagicState.ToString(), ChatMessageType.Broadcast));
|
|
session.Network.EnqueueSend(new GameMessageSystemChat($"IsMovingOrAnimating: {physicsObj.IsMovingOrAnimating}", ChatMessageType.Broadcast));
|
|
session.Network.EnqueueSend(new GameMessageSystemChat($"PendingActions: {pendingActions.Count}", ChatMessageType.Broadcast));
|
|
session.Network.EnqueueSend(new GameMessageSystemChat($"CurrAnim: {currAnim?.Value.Anim.ID:X8}", ChatMessageType.Broadcast));
|
|
}
|
|
|
|
[CommandHandler("fixcast", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, "Fixes magic casting if locked up for an extended time")]
|
|
public static void HandleFixCast(Session session, params string[] parameters)
|
|
{
|
|
var magicState = session.Player.MagicState;
|
|
|
|
if (magicState.IsCasting && DateTime.UtcNow - magicState.StartTime > TimeSpan.FromSeconds(5))
|
|
{
|
|
session.Network.EnqueueSend(new GameEventCommunicationTransientString(session, "Fixed casting state"));
|
|
session.Player.SendUseDoneEvent();
|
|
magicState.OnCastDone();
|
|
}
|
|
}
|
|
|
|
[CommandHandler("castmeter", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, "Shows the fast casting efficiency meter")]
|
|
public static void HandleCastMeter(Session session, params string[] parameters)
|
|
{
|
|
if (parameters.Length == 0)
|
|
{
|
|
session.Player.MagicState.CastMeter = !session.Player.MagicState.CastMeter;
|
|
}
|
|
else
|
|
{
|
|
if (parameters[0].Equals("on", StringComparison.OrdinalIgnoreCase))
|
|
session.Player.MagicState.CastMeter = true;
|
|
else
|
|
session.Player.MagicState.CastMeter = false;
|
|
}
|
|
session.Network.EnqueueSend(new GameMessageSystemChat($"Cast efficiency meter {(session.Player.MagicState.CastMeter ? "enabled" : "disabled")}", ChatMessageType.Broadcast));
|
|
}
|
|
|
|
private static List<string> configList = new List<string>()
|
|
{
|
|
"Common settings:\nConfirmVolatileRareUse, MainPackPreferred, SalvageMultiple, SideBySideVitals, UseCraftSuccessDialog",
|
|
"Interaction settings:\nAcceptLootPermits, AllowGive, AppearOffline, AutoAcceptFellowRequest, DragItemOnPlayerOpensSecureTrade, FellowshipShareLoot, FellowshipShareXP, IgnoreAllegianceRequests, IgnoreFellowshipRequests, IgnoreTradeRequests, UseDeception",
|
|
"UI settings:\nCoordinatesOnRadar, DisableDistanceFog, DisableHouseRestrictionEffects, DisableMostWeatherEffects, FilterLanguage, LockUI, PersistentAtDay, ShowCloak, ShowHelm, ShowTooltips, SpellDuration, TimeStamp, ToggleRun, UseMouseTurning",
|
|
"Chat settings:\nHearAllegianceChat, HearGeneralChat, HearLFGChat, HearRoleplayChat, HearSocietyChat, HearTradeChat, HearPKDeaths, StayInChatMode",
|
|
"Combat settings:\nAdvancedCombatUI, AutoRepeatAttack, AutoTarget, LeadMissileTargets, UseChargeAttack, UseFastMissiles, ViewCombatTarget, VividTargetingIndicator",
|
|
"Character display settings:\nDisplayAge, DisplayAllegianceLogonNotifications, DisplayChessRank, DisplayDateOfBirth, DisplayFishingSkill, DisplayNumberCharacterTitles, DisplayNumberDeaths"
|
|
};
|
|
|
|
/// <summary>
|
|
/// Mapping of GDLE -> ACE CharacterOptions
|
|
/// </summary>
|
|
private static Dictionary<string, string> translateOptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
// Common
|
|
{ "ConfirmVolatileRareUse", "ConfirmUseOfRareGems" },
|
|
{ "MainPackPreferred", "UseMainPackAsDefaultForPickingUpItems" },
|
|
{ "SalvageMultiple", "SalvageMultipleMaterialsAtOnce" },
|
|
{ "SideBySideVitals", "SideBySideVitals" },
|
|
{ "UseCraftSuccessDialog", "UseCraftingChanceOfSuccessDialog" },
|
|
|
|
// Interaction
|
|
{ "AcceptLootPermits", "AcceptCorpseLootingPermissions" },
|
|
{ "AllowGive", "LetOtherPlayersGiveYouItems" },
|
|
{ "AppearOffline", "AppearOffline" },
|
|
{ "AutoAcceptFellowRequest", "AutomaticallyAcceptFellowshipRequests" },
|
|
{ "DragItemOnPlayerOpensSecureTrade", "DragItemToPlayerOpensTrade" },
|
|
{ "FellowshipShareLoot", "ShareFellowshipLoot" },
|
|
{ "FellowshipShareXP", "ShareFellowshipExpAndLuminance" },
|
|
{ "IgnoreAllegianceRequests", "IgnoreAllegianceRequests" },
|
|
{ "IgnoreFellowshipRequests", "IgnoreFellowshipRequests" },
|
|
{ "IgnoreTradeRequests", "IgnoreAllTradeRequests" },
|
|
{ "UseDeception", "AttemptToDeceiveOtherPlayers" },
|
|
|
|
// UI
|
|
{ "CoordinatesOnRadar", "ShowCoordinatesByTheRadar" },
|
|
{ "DisableDistanceFog", "DisableDistanceFog" },
|
|
{ "DisableHouseRestrictionEffects", "DisableHouseRestrictionEffects" },
|
|
{ "DisableMostWeatherEffects", "DisableMostWeatherEffects" },
|
|
{ "FilterLanguage", "FilterLanguage" },
|
|
{ "LockUI", "LockUI" },
|
|
{ "PersistentAtDay", "AlwaysDaylightOutdoors" },
|
|
{ "ShowCloak", "ShowYourCloak" },
|
|
{ "ShowHelm", "ShowYourHelmOrHeadGear" },
|
|
{ "ShowTooltips", "Display3dTooltips" },
|
|
{ "SpellDuration", "DisplaySpellDurations" },
|
|
{ "TimeStamp", "DisplayTimestamps" },
|
|
{ "ToggleRun", "RunAsDefaultMovement" },
|
|
{ "UseMouseTurning", "UseMouseTurning" },
|
|
|
|
// Chat
|
|
{ "HearAllegianceChat", "ListenToAllegianceChat" },
|
|
{ "HearGeneralChat", "ListenToGeneralChat" },
|
|
{ "HearLFGChat", "ListenToLFGChat" },
|
|
{ "HearRoleplayChat", "ListentoRoleplayChat" },
|
|
{ "HearSocietyChat", "ListenToSocietyChat" },
|
|
{ "HearTradeChat", "ListenToTradeChat" },
|
|
{ "HearPKDeaths", "ListenToPKDeathMessages" },
|
|
{ "StayInChatMode", "StayInChatModeAfterSendingMessage" },
|
|
|
|
// Combat
|
|
{ "AdvancedCombatUI", "AdvancedCombatInterface" },
|
|
{ "AutoRepeatAttack", "AutoRepeatAttacks" },
|
|
{ "AutoTarget", "AutoTarget" },
|
|
{ "LeadMissileTargets", "LeadMissileTargets" },
|
|
{ "UseChargeAttack", "UseChargeAttack" },
|
|
{ "UseFastMissiles", "UseFastMissiles" },
|
|
{ "ViewCombatTarget", "KeepCombatTargetsInView" },
|
|
{ "VividTargetingIndicator", "VividTargetingIndicator" },
|
|
|
|
// Character Display
|
|
{ "DisplayAge", "AllowOthersToSeeYourAge" },
|
|
{ "DisplayAllegianceLogonNotifications", "ShowAllegianceLogons" },
|
|
{ "DisplayChessRank", "AllowOthersToSeeYourChessRank" },
|
|
{ "DisplayDateOfBirth", "AllowOthersToSeeYourDateOfBirth" },
|
|
{ "DisplayFishingSkill", "AllowOthersToSeeYourFishingSkill" },
|
|
{ "DisplayNumberCharacterTitles", "AllowOthersToSeeYourNumberOfTitles" },
|
|
{ "DisplayNumberDeaths", "AllowOthersToSeeYourNumberOfDeaths" },
|
|
};
|
|
|
|
/// <summary>
|
|
/// Manually sets a character option on the server. Use /config list to see a list of settings.
|
|
/// </summary>
|
|
[CommandHandler("config", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, 1, "Manually sets a character option on the server.\nUse /config list to see a list of settings.", "<setting> <on/off>")]
|
|
public static void HandleConfig(Session session, params string[] parameters)
|
|
{
|
|
if (!PropertyManager.GetBool("player_config_command").Item)
|
|
{
|
|
session.Network.EnqueueSend(new GameMessageSystemChat("The command \"config\" is not currently enabled on this server.", ChatMessageType.Broadcast));
|
|
return;
|
|
}
|
|
|
|
// /config list - show character options
|
|
if (parameters[0].Equals("list", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
foreach (var line in configList)
|
|
session.Network.EnqueueSend(new GameMessageSystemChat(line, ChatMessageType.Broadcast));
|
|
|
|
return;
|
|
}
|
|
|
|
// translate GDLE CharacterOptions for existing plugins
|
|
if (!translateOptions.TryGetValue(parameters[0], out var param) || !Enum.TryParse(param, out CharacterOption characterOption))
|
|
{
|
|
session.Network.EnqueueSend(new GameMessageSystemChat($"Unknown character option: {parameters[0]}", ChatMessageType.Broadcast));
|
|
return;
|
|
}
|
|
|
|
var option = session.Player.GetCharacterOption(characterOption);
|
|
|
|
// modes of operation:
|
|
// on / off / toggle
|
|
|
|
// - if none specified, default to toggle
|
|
var mode = "toggle";
|
|
|
|
if (parameters.Length > 1)
|
|
{
|
|
if (parameters[1].Equals("on", StringComparison.OrdinalIgnoreCase))
|
|
mode = "on";
|
|
else if (parameters[1].Equals("off", StringComparison.OrdinalIgnoreCase))
|
|
mode = "off";
|
|
}
|
|
|
|
// set character option
|
|
if (mode.Equals("on"))
|
|
option = true;
|
|
else if (mode.Equals("off"))
|
|
option = false;
|
|
else
|
|
option = !option;
|
|
|
|
session.Player.SetCharacterOption(characterOption, option);
|
|
|
|
session.Network.EnqueueSend(new GameMessageSystemChat($"Character option {parameters[0]} is now {(option ? "on" : "off")}.", ChatMessageType.Broadcast));
|
|
|
|
// update client
|
|
session.Network.EnqueueSend(new GameEventPlayerDescription(session));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Force resend of all visible objects known to this player. Can fix rare cases of invisible object bugs.
|
|
/// Can only be used once every 5 mins max.
|
|
/// </summary>
|
|
[CommandHandler("objsend", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, "Force resend of all visible objects known to this player. Can fix rare cases of invisible object bugs. Can only be used once every 5 mins max.")]
|
|
public static void HandleObjSend(Session session, params string[] parameters)
|
|
{
|
|
// a good repro spot for this is the first room after the door in facility hub
|
|
// in the portal drop / staircase room, the VisibleCells do not have the room after the door
|
|
// however, the room after the door *does* have the portal drop / staircase room in its VisibleCells (the inverse relationship is imbalanced)
|
|
// not sure how to fix this atm, seems like it triggers a client bug..
|
|
|
|
if (DateTime.UtcNow - session.Player.PrevObjSend < TimeSpan.FromMinutes(5))
|
|
{
|
|
session.Player.SendTransientError("You have used this command too recently!");
|
|
return;
|
|
}
|
|
|
|
var creaturesOnly = parameters.Length > 0 && parameters[0].Contains("creature", StringComparison.OrdinalIgnoreCase);
|
|
|
|
var knownObjs = session.Player.GetKnownObjects();
|
|
|
|
foreach (var knownObj in knownObjs)
|
|
{
|
|
if (creaturesOnly && !(knownObj is Creature))
|
|
continue;
|
|
|
|
session.Player.RemoveTrackedObject(knownObj, false);
|
|
session.Player.TrackObject(knownObj);
|
|
}
|
|
session.Player.PrevObjSend = DateTime.UtcNow;
|
|
}
|
|
|
|
// show player ace server versions
|
|
[CommandHandler("aceversion", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, "Shows this server's version data")]
|
|
public static void HandleACEversion(Session session, params string[] parameters)
|
|
{
|
|
if (!PropertyManager.GetBool("version_info_enabled").Item)
|
|
{
|
|
session.Network.EnqueueSend(new GameMessageSystemChat("The command \"aceversion\" is not currently enabled on this server.", ChatMessageType.Broadcast));
|
|
return;
|
|
}
|
|
|
|
var msg = ServerBuildInfo.GetVersionInfo();
|
|
|
|
session.Network.EnqueueSend(new GameMessageSystemChat(msg, ChatMessageType.WorldBroadcast));
|
|
}
|
|
|
|
// reportbug < code | content > < description >
|
|
[CommandHandler("reportbug", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, 2,
|
|
"Generate a Bug Report",
|
|
"<category> <description>\n" +
|
|
"This command generates a URL for you to copy and paste into your web browser to submit for review by server operators and developers.\n" +
|
|
"Category can be the following:\n" +
|
|
"Creature\n" +
|
|
"NPC\n" +
|
|
"Item\n" +
|
|
"Quest\n" +
|
|
"Recipe\n" +
|
|
"Landblock\n" +
|
|
"Mechanic\n" +
|
|
"Code\n" +
|
|
"Other\n" +
|
|
"For the first three options, the bug report will include identifiers for what you currently have selected/targeted.\n" +
|
|
"After category, please include a brief description of the issue, which you can further detail in the report on the website.\n" +
|
|
"Examples:\n" +
|
|
"/reportbug creature Drudge Prowler is over powered\n" +
|
|
"/reportbug npc Ulgrim doesn't know what to do with Sake\n" +
|
|
"/reportbug quest I can't enter the portal to the Lost City of Frore\n" +
|
|
"/reportbug recipe I cannot combine Bundle of Arrowheads with Bundle of Arrowshafts\n" +
|
|
"/reportbug code I was killed by a Non-Player Killer\n"
|
|
)]
|
|
public static void HandleReportbug(Session session, params string[] parameters)
|
|
{
|
|
if (!PropertyManager.GetBool("reportbug_enabled").Item)
|
|
{
|
|
session.Network.EnqueueSend(new GameMessageSystemChat("The command \"reportbug\" is not currently enabled on this server.", ChatMessageType.Broadcast));
|
|
return;
|
|
}
|
|
|
|
var category = parameters[0];
|
|
var description = "";
|
|
|
|
for (var i = 1; i < parameters.Length; i++)
|
|
description += parameters[i] + " ";
|
|
|
|
description.Trim();
|
|
|
|
switch (category.ToLower())
|
|
{
|
|
case "creature":
|
|
case "npc":
|
|
case "quest":
|
|
case "item":
|
|
case "recipe":
|
|
case "landblock":
|
|
case "mechanic":
|
|
case "code":
|
|
case "other":
|
|
break;
|
|
default:
|
|
category = "Other";
|
|
break;
|
|
}
|
|
|
|
var sn = ConfigManager.Config.Server.WorldName;
|
|
var c = session.Player.Name;
|
|
|
|
var st = "ACE";
|
|
|
|
//var versions = ServerBuildInfo.GetVersionInfo();
|
|
var databaseVersion = DatabaseManager.World.GetVersion();
|
|
var sv = ServerBuildInfo.FullVersion;
|
|
var pv = databaseVersion.PatchVersion;
|
|
|
|
//var ct = PropertyManager.GetString("reportbug_content_type").Item;
|
|
var cg = category.ToLower();
|
|
|
|
var w = "";
|
|
var g = "";
|
|
|
|
if (cg == "creature" || cg == "npc"|| cg == "item" || cg == "item")
|
|
{
|
|
var objectId = new ObjectGuid();
|
|
if (session.Player.HealthQueryTarget.HasValue || session.Player.ManaQueryTarget.HasValue || session.Player.CurrentAppraisalTarget.HasValue)
|
|
{
|
|
if (session.Player.HealthQueryTarget.HasValue)
|
|
objectId = new ObjectGuid((uint)session.Player.HealthQueryTarget);
|
|
else if (session.Player.ManaQueryTarget.HasValue)
|
|
objectId = new ObjectGuid((uint)session.Player.ManaQueryTarget);
|
|
else
|
|
objectId = new ObjectGuid((uint)session.Player.CurrentAppraisalTarget);
|
|
|
|
//var wo = session.Player.CurrentLandblock?.GetObject(objectId);
|
|
|
|
var wo = session.Player.FindObject(objectId.Full, Player.SearchLocations.Everywhere);
|
|
|
|
if (wo != null)
|
|
{
|
|
w = $"{wo.WeenieClassId}";
|
|
g = $"0x{wo.Guid:X8}";
|
|
}
|
|
}
|
|
}
|
|
|
|
var l = session.Player.Location.ToLOCString();
|
|
|
|
var issue = description;
|
|
|
|
var urlbase = $"https://www.accpp.net/bug?";
|
|
|
|
var url = urlbase;
|
|
if (sn.Length > 0)
|
|
url += $"sn={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(sn))}";
|
|
if (c.Length > 0)
|
|
url += $"&c={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(c))}";
|
|
if (st.Length > 0)
|
|
url += $"&st={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(st))}";
|
|
if (sv.Length > 0)
|
|
url += $"&sv={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(sv))}";
|
|
if (pv.Length > 0)
|
|
url += $"&pv={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(pv))}";
|
|
//if (ct.Length > 0)
|
|
// url += $"&ct={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(ct))}";
|
|
if (cg.Length > 0)
|
|
{
|
|
if (cg == "npc")
|
|
cg = cg.ToUpper();
|
|
else
|
|
cg = char.ToUpper(cg[0]) + cg.Substring(1);
|
|
url += $"&cg={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(cg))}";
|
|
}
|
|
if (w.Length > 0)
|
|
url += $"&w={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(w))}";
|
|
if (g.Length > 0)
|
|
url += $"&g={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(g))}";
|
|
if (l.Length > 0)
|
|
url += $"&l={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(l))}";
|
|
if (issue.Length > 0)
|
|
url += $"&i={Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(issue))}";
|
|
|
|
var msg = "\n\n\n\n";
|
|
msg += "Bug Report - Copy and Paste the following URL into your browser to submit a bug report\n";
|
|
msg += "-=-\n";
|
|
msg += $"{url}\n";
|
|
msg += "-=-\n";
|
|
msg += "\n\n\n\n";
|
|
|
|
session.Network.EnqueueSend(new GameMessageSystemChat(msg, ChatMessageType.AdminTell));
|
|
}
|
|
}
|
|
}
|