using Server.Accounting; using Server.Commands; using Server.Items; using Server.Misc; using Server.Multis; using Server.Network; using Server.Prompts; using System; using System.Collections; using System.Collections.Generic; using System.Net; using System.Text; namespace Server.Gumps { public enum AdminGumpPage { Information_General, Information_Perf, Administer, Clients, Accounts, Accounts_Shared, Firewall, Administer_WorldBuilding, Administer_Server, Administer_Access, Administer_Access_Lockdown, Administer_Commands, Administer_Maintenance, ClientInfo, AccountDetails, AccountDetails_Information, AccountDetails_Characters, AccountDetails_Access, AccountDetails_Access_ClientIPs, AccountDetails_Access_Restrictions, AccountDetails_Comments, AccountDetails_Tags, AccountDetails_ChangePassword, AccountDetails_ChangeAccess, FirewallInfo } public class AdminGump : Gump { private readonly Mobile m_From; private readonly AdminGumpPage m_PageType; private readonly ArrayList m_List; private readonly int m_ListPage; private readonly object m_State; private const int LabelColor = 0x7FFF; private const int SelectedColor = 0x421F; private const int DisabledColor = 0x4210; private const int LabelColor32 = 0xFFFFFF; private const int SelectedColor32 = 0x8080FF; private const int DisabledColor32 = 0x808080; private const int LabelHue = 0x480; private const int GreenHue = 0x40; private const int RedHue = 0x20; public void AddPageButton(int x, int y, int buttonID, string text, AdminGumpPage page, params AdminGumpPage[] subPages) { bool isSelection = (m_PageType == page); for (int i = 0; !isSelection && i < subPages.Length; ++i) isSelection = (m_PageType == subPages[i]); AddSelectedButton(x, y, buttonID, text, isSelection); } public void AddSelectedButton(int x, int y, int buttonID, string text, bool isSelection) { AddButton(x, y - 1, isSelection ? 4006 : 4005, 4007, buttonID, GumpButtonType.Reply, 0); AddHtml(x + 35, y, 200, 20, Color(text, isSelection ? SelectedColor32 : LabelColor32), false, false); } public void AddButtonLabeled(int x, int y, int buttonID, string text) { AddButton(x, y - 1, 4005, 4007, buttonID, GumpButtonType.Reply, 0); AddHtml(x + 35, y, 240, 20, Color(text, LabelColor32), false, false); } public string Center(string text) { return string.Format("
{0}
", text); } public string Color(string text, int color) { return string.Format("{1}", color, text); } public void AddBlackAlpha(int x, int y, int width, int height) { AddImageTiled(x, y, width, height, 2624); AddAlphaRegion(x, y, width, height); } public int GetButtonID(int type, int index) { return 1 + (index * 11) + type; } public static string FormatTimeSpan(TimeSpan ts) { return string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D2}", ts.Days, ts.Hours % 24, ts.Minutes % 60, ts.Seconds % 60); } public static string FormatByteAmount(long totalBytes) { if (totalBytes > 1000000000) return string.Format("{0:F1} GB", (double)totalBytes / 1073741824); if (totalBytes > 1000000) return string.Format("{0:F1} MB", (double)totalBytes / 1048576); if (totalBytes > 1000) return string.Format("{0:F1} KB", (double)totalBytes / 1024); return string.Format("{0} Bytes", totalBytes); } public static void Initialize() { CommandSystem.Register("Admin", AccessLevel.Administrator, Admin_OnCommand); } [Usage("Admin")] [Description("Opens an interface providing server information and administration features including client, account, and firewall management.")] public static void Admin_OnCommand(CommandEventArgs e) { e.Mobile.SendGump(new AdminGump(e.Mobile, AdminGumpPage.Clients, 0, null, null, null)); } public static int GetHueFor(Mobile m) { if (m == null) return LabelHue; switch (m.AccessLevel) { case AccessLevel.Owner: return 0x516; case AccessLevel.Developer: return 0x516; case AccessLevel.Administrator: return 0x516; case AccessLevel.Seer: return 0x144; case AccessLevel.GameMaster: return 0x21; case AccessLevel.Counselor: return 0x2; case AccessLevel.VIP: case AccessLevel.Player: default: { if (m.Murderer) return 0x21; else if (m.Criminal) return 0x3B1; return 0x58; } } } private static readonly string[] m_AccessLevelStrings = new string[] { "Player", "VIP", "Counselor", "Decorator", "Spawner", "Game Master", "Seer", "Administrator", "Developer", "Co-Owner", "Owner" }; public static string FormatAccessLevel(AccessLevel level) { int v = (int)level; if (v >= 0 && v < m_AccessLevelStrings.Length) return m_AccessLevelStrings[v]; return "Unknown"; } public AdminGump(Mobile from, AdminGumpPage pageType, int listPage, ArrayList list, string notice, object state) : base(50, 40) { from.CloseGump(typeof(AdminGump)); m_From = from; m_PageType = pageType; m_ListPage = listPage; m_State = state; m_List = list; AddPage(0); AddBackground(0, 0, 420, 440, 5054); AddBlackAlpha(10, 10, 170, 100); AddBlackAlpha(190, 10, 220, 100); AddBlackAlpha(10, 120, 400, 260); AddBlackAlpha(10, 390, 400, 40); AddPageButton(10, 10, GetButtonID(0, 0), "INFORMATION", AdminGumpPage.Information_General, AdminGumpPage.Information_Perf); AddPageButton(10, 30, GetButtonID(0, 1), "ADMINISTER", AdminGumpPage.Administer, AdminGumpPage.Administer_Access, AdminGumpPage.Administer_Commands, AdminGumpPage.Administer_Server, AdminGumpPage.Administer_WorldBuilding, AdminGumpPage.Administer_Access_Lockdown, AdminGumpPage.Administer_Maintenance); AddPageButton(10, 50, GetButtonID(0, 2), "CLIENT LIST", AdminGumpPage.Clients, AdminGumpPage.ClientInfo); AddPageButton(10, 70, GetButtonID(0, 3), "ACCOUNT LIST", AdminGumpPage.Accounts, AdminGumpPage.Accounts_Shared, AdminGumpPage.AccountDetails, AdminGumpPage.AccountDetails_Information, AdminGumpPage.AccountDetails_Characters, AdminGumpPage.AccountDetails_Access, AdminGumpPage.AccountDetails_Access_ClientIPs, AdminGumpPage.AccountDetails_Access_Restrictions, AdminGumpPage.AccountDetails_Comments, AdminGumpPage.AccountDetails_Tags, AdminGumpPage.AccountDetails_ChangeAccess, AdminGumpPage.AccountDetails_ChangePassword); AddPageButton(10, 90, GetButtonID(0, 4), "FIREWALL", AdminGumpPage.Firewall, AdminGumpPage.FirewallInfo); if (notice != null) AddHtml(12, 392, 396, 36, Color(notice, LabelColor32), false, false); switch (pageType) { case AdminGumpPage.Information_General: { int banned = 0; int active = 0; foreach (Account acct in Accounts.GetAccounts()) { if (acct.Banned) ++banned; else ++active; } AddLabel(20, 130, LabelHue, "Active Accounts:"); AddLabel(150, 130, LabelHue, active.ToString()); AddLabel(20, 150, LabelHue, "Banned Accounts:"); AddLabel(150, 150, LabelHue, banned.ToString()); AddLabel(20, 170, LabelHue, "Firewalled:"); AddLabel(150, 170, LabelHue, Firewall.List.Count.ToString()); AddLabel(20, 190, LabelHue, "Clients:"); AddLabel(150, 190, LabelHue, NetState.Instances.Count.ToString()); AddLabel(20, 210, LabelHue, "Mobiles:"); AddLabel(150, 210, LabelHue, World.Mobiles.Count.ToString()); AddLabel(20, 230, LabelHue, "Mobile Scripts:"); AddLabel(150, 230, LabelHue, Core.ScriptMobiles.ToString()); AddLabel(20, 250, LabelHue, "Items:"); AddLabel(150, 250, LabelHue, World.Items.Count.ToString()); AddLabel(20, 270, LabelHue, "Item Scripts:"); AddLabel(150, 270, LabelHue, Core.ScriptItems.ToString()); AddLabel(20, 290, LabelHue, "Uptime:"); AddLabel(150, 290, LabelHue, FormatTimeSpan(DateTime.UtcNow - Clock.ServerStart)); AddLabel(20, 310, LabelHue, "Memory:"); AddLabel(150, 310, LabelHue, FormatByteAmount(GC.GetTotalMemory(false))); AddLabel(20, 330, LabelHue, "Framework:"); AddLabel(150, 330, LabelHue, Environment.Version.ToString()); AddLabel(20, 350, LabelHue, "Operating System: "); string os = Environment.OSVersion.ToString(); os = os.Replace("Service Pack", "SP"); AddLabel(150, 350, LabelHue, os); AddPageButton(200, 20, GetButtonID(0, 0), "General", AdminGumpPage.Information_General); AddPageButton(200, 40, GetButtonID(0, 5), "Performance", AdminGumpPage.Information_Perf); break; } case AdminGumpPage.Information_Perf: { AddLabel(20, 130, LabelHue, "Cycles Per Second:"); AddLabel(40, 150, LabelHue, "Current: " + Core.CyclesPerSecond.ToString("N2")); AddLabel(40, 170, LabelHue, "Average: " + Core.AverageCPS.ToString("N2")); StringBuilder sb = new StringBuilder(); int curUser, maxUser; int curIOCP, maxIOCP; System.Threading.ThreadPool.GetAvailableThreads(out curUser, out curIOCP); System.Threading.ThreadPool.GetMaxThreads(out maxUser, out maxIOCP); sb.Append("Worker Threads:
Capacity: "); sb.Append(maxUser); sb.Append("
Available: "); sb.Append(curUser); sb.Append("
Usage: "); sb.Append(((maxUser - curUser) * 100) / maxUser); sb.Append("%

IOCP Threads:
Capacity: "); sb.Append(maxIOCP); sb.Append("
Available: "); sb.Append(curIOCP); sb.Append("
Usage: "); sb.Append(((maxIOCP - curIOCP) * 100) / maxIOCP); sb.Append("%"); List pools = BufferPool.Pools; lock (pools) { for (int i = 0; i < pools.Count; ++i) { BufferPool pool = pools[i]; string name; int freeCount; int initialCapacity; int currentCapacity; int bufferSize; int misses; pool.GetInfo(out name, out freeCount, out initialCapacity, out currentCapacity, out bufferSize, out misses); if (sb.Length > 0) sb.Append("

"); sb.Append(name); sb.Append("
Size: "); sb.Append(FormatByteAmount(bufferSize)); sb.Append("
Capacity: "); sb.Append(currentCapacity); sb.Append(" ("); sb.Append(misses); sb.Append(" misses)
Available: "); sb.Append(freeCount); sb.Append("
Usage: "); sb.Append(((currentCapacity - freeCount) * 100) / currentCapacity); sb.Append("% : "); sb.Append(FormatByteAmount((currentCapacity - freeCount) * bufferSize)); sb.Append(" of "); sb.Append(FormatByteAmount(currentCapacity * bufferSize)); } } AddLabel(20, 200, LabelHue, "Pooling:"); AddHtml(20, 220, 380, 150, sb.ToString(), true, true); AddPageButton(200, 20, GetButtonID(0, 0), "General", AdminGumpPage.Information_General); AddPageButton(200, 40, GetButtonID(0, 5), "Performance", AdminGumpPage.Information_Perf); break; } case AdminGumpPage.Administer_WorldBuilding: { AddHtml(10, 125, 400, 20, Color(Center("Generating"), LabelColor32), false, false); AddButtonLabeled(20, 150, GetButtonID(3, 101), "Create World"); AddButtonLabeled(20, 175, GetButtonID(3, 102), "Delete World"); AddButtonLabeled(20, 200, GetButtonID(3, 103), "Recreate World"); AddHtml(20, 275, 400, 30, Color(Center("Statics"), LabelColor32), false, false); AddButtonLabeled(20, 300, GetButtonID(3, 110), "Freeze (Target)"); AddButtonLabeled(20, 325, GetButtonID(3, 111), "Freeze (World)"); AddButtonLabeled(20, 350, GetButtonID(3, 112), "Freeze (Map)"); AddButtonLabeled(220, 300, GetButtonID(3, 120), "Unfreeze (Target)"); AddButtonLabeled(220, 325, GetButtonID(3, 121), "Unfreeze (World)"); AddButtonLabeled(220, 350, GetButtonID(3, 122), "Unfreeze (Map)"); goto case AdminGumpPage.Administer; } case AdminGumpPage.Administer_Server: { AddHtml(10, 125, 400, 20, Color(Center("Server"), LabelColor32), false, false); AddButtonLabeled(20, 150, GetButtonID(3, 200), "Save"); AddButtonLabeled(20, 180, GetButtonID(3, 201), "Shutdown (With Save)"); AddButtonLabeled(20, 200, GetButtonID(3, 202), "Shutdown (Without Save)"); AddButtonLabeled(20, 230, GetButtonID(3, 203), "Shutdown & Restart (With Save)"); AddButtonLabeled(20, 250, GetButtonID(3, 204), "Shutdown & Restart (Without Save)"); AddHtml(10, 295, 400, 20, Color(Center("Broadcast"), LabelColor32), false, false); AddTextField(20, 320, 380, 20, 0); AddButtonLabeled(20, 350, GetButtonID(3, 210), "To Everyone"); AddButtonLabeled(220, 350, GetButtonID(3, 211), "To Staff"); goto case AdminGumpPage.Administer; } case AdminGumpPage.Administer_Access_Lockdown: { AddHtml(10, 125, 400, 20, Color(Center("Server Lockdown"), LabelColor32), false, false); AddHtml(20, 150, 380, 80, Color("When enabled, only clients with an access level equal to or greater than the specified lockdown level may access the server. After setting a lockdown level, use the Purge Invalid Clients button to disconnect those clients without access.", LabelColor32), false, false); AccessLevel level = AccountHandler.LockdownLevel; bool isLockedDown = (level > AccessLevel.VIP); AddSelectedButton(20, 230, GetButtonID(3, 500), "Not Locked Down", !isLockedDown); AddSelectedButton(20, 260, GetButtonID(3, 504), "Administrators", (isLockedDown && level <= AccessLevel.Administrator)); AddSelectedButton(20, 280, GetButtonID(3, 503), "Seers", (isLockedDown && level <= AccessLevel.Seer)); AddSelectedButton(20, 300, GetButtonID(3, 502), "Game Masters", (isLockedDown && level <= AccessLevel.GameMaster)); AddSelectedButton(20, 320, GetButtonID(3, 501), "Counselors", (isLockedDown && level <= AccessLevel.Counselor)); AddButtonLabeled(20, 350, GetButtonID(3, 510), "Purge Invalid Clients"); goto case AdminGumpPage.Administer; } case AdminGumpPage.Administer_Access: { AddHtml(10, 125, 400, 20, Color(Center("Access"), LabelColor32), false, false); AddHtml(10, 155, 400, 20, Color(Center("Connectivity"), LabelColor32), false, false); AddButtonLabeled(20, 180, GetButtonID(3, 300), "Kick"); AddButtonLabeled(220, 180, GetButtonID(3, 301), "Ban"); AddButtonLabeled(20, 210, GetButtonID(3, 302), "Firewall"); AddButtonLabeled(220, 210, GetButtonID(3, 303), "Lockdown"); AddHtml(10, 245, 400, 20, Color(Center("Staff"), LabelColor32), false, false); AddButtonLabeled(20, 270, GetButtonID(3, 310), "Make Player"); AddButtonLabeled(20, 290, GetButtonID(3, 311), "Make Counselor"); AddButtonLabeled(20, 310, GetButtonID(3, 312), "Make Game Master"); AddButtonLabeled(20, 330, GetButtonID(3, 313), "Make Seer"); if (from.AccessLevel > AccessLevel.Administrator) { AddButtonLabeled(220, 270, GetButtonID(3, 314), "Make Administrator"); if (from.AccessLevel > AccessLevel.Developer) { AddButtonLabeled(220, 290, GetButtonID(3, 315), "Make Developer"); if (from.AccessLevel >= AccessLevel.Owner) AddButtonLabeled(220, 310, GetButtonID(3, 316), "Make Owner"); } } goto case AdminGumpPage.Administer; } case AdminGumpPage.Administer_Maintenance: { AddHtml(10, 125, 400, 20, Color(Center("Maintenance"), LabelColor32), false, false); AddButtonLabeled(20, 150, GetButtonID(3, 600), "Rebuild Categorization"); AddButtonLabeled(220, 150, GetButtonID(3, 601), "Generate Documentation"); AddButtonLabeled(20, 180, GetButtonID(3, 602), "Rebuild Bounds.bin"); AddHtml(10, 210, 400, 20, Color(Center("Profiling"), LabelColor32), false, false); AddButtonLabeled(20, 240, GetButtonID(3, 604), "Dump Timers"); AddButtonLabeled(220, 240, GetButtonID(3, 605), "Count Objects"); AddButtonLabeled(20, 270, GetButtonID(3, 606), "Profile World"); AddButtonLabeled(220, 270, GetButtonID(3, 607), "Write Profiles"); AddButtonLabeled(20, 300, GetButtonID(3, 608), "Trace Internal"); AddButtonLabeled(220, 300, GetButtonID(3, 609), "Trace Expanded"); AddButtonLabeled(20, 330, GetButtonID(3, 610), "Toggle Profiles"); goto case AdminGumpPage.Administer; } case AdminGumpPage.Administer_Commands: { AddHtml(10, 125, 400, 20, Color(Center("Commands"), LabelColor32), false, false); AddButtonLabeled(20, 150, GetButtonID(3, 400), "Add"); AddButtonLabeled(220, 150, GetButtonID(3, 401), "Remove"); AddButtonLabeled(20, 170, GetButtonID(3, 402), "Dupe"); AddButtonLabeled(220, 170, GetButtonID(3, 403), "Dupe in bag"); AddButtonLabeled(20, 200, GetButtonID(3, 404), "Properties"); AddButtonLabeled(220, 200, GetButtonID(3, 405), "Skills"); AddButtonLabeled(20, 230, GetButtonID(3, 406), "Mortal"); AddButtonLabeled(220, 230, GetButtonID(3, 407), "Immortal"); AddButtonLabeled(20, 250, GetButtonID(3, 408), "Squelch"); AddButtonLabeled(220, 250, GetButtonID(3, 409), "Unsquelch"); AddButtonLabeled(20, 270, GetButtonID(3, 410), "Freeze"); AddButtonLabeled(220, 270, GetButtonID(3, 411), "Unfreeze"); AddButtonLabeled(20, 290, GetButtonID(3, 412), "Hide"); AddButtonLabeled(220, 290, GetButtonID(3, 413), "Unhide"); AddButtonLabeled(20, 310, GetButtonID(3, 414), "Kill"); AddButtonLabeled(220, 310, GetButtonID(3, 415), "Resurrect"); AddButtonLabeled(20, 330, GetButtonID(3, 416), "Move"); AddButtonLabeled(220, 330, GetButtonID(3, 417), "Wipe"); AddButtonLabeled(20, 350, GetButtonID(3, 418), "Teleport"); AddButtonLabeled(220, 350, GetButtonID(3, 419), "Teleport (Multiple)"); goto case AdminGumpPage.Administer; } case AdminGumpPage.Administer: { AddPageButton(200, 10, GetButtonID(3, 0), "World Building", AdminGumpPage.Administer_WorldBuilding); AddPageButton(200, 30, GetButtonID(3, 1), "Server", AdminGumpPage.Administer_Server); AddPageButton(200, 50, GetButtonID(3, 2), "Access", AdminGumpPage.Administer_Access, AdminGumpPage.Administer_Access_Lockdown); AddPageButton(200, 70, GetButtonID(3, 3), "Commands", AdminGumpPage.Administer_Commands); AddPageButton(200, 90, GetButtonID(3, 4), "Maintenance", AdminGumpPage.Administer_Maintenance); break; } case AdminGumpPage.Clients: { if (m_List == null) { m_List = new ArrayList(NetState.Instances); m_List.Sort(NetStateComparer.Instance); } AddClientHeader(); AddLabelCropped(12, 120, 81, 20, LabelHue, "Name"); AddLabelCropped(95, 120, 81, 20, LabelHue, "Account"); AddLabelCropped(178, 120, 81, 20, LabelHue, "Access Level"); AddLabelCropped(273, 120, 109, 20, LabelHue, "IP Address"); if (listPage > 0) AddButton(375, 122, 0x15E3, 0x15E7, GetButtonID(1, 0), GumpButtonType.Reply, 0); else AddImage(375, 122, 0x25EA); if ((listPage + 1) * 12 < m_List.Count) AddButton(392, 122, 0x15E1, 0x15E5, GetButtonID(1, 1), GumpButtonType.Reply, 0); else AddImage(392, 122, 0x25E6); if (m_List.Count == 0) AddLabel(12, 140, LabelHue, "There are no clients to display."); for (int i = 0, index = (listPage * 12); i < 12 && index >= 0 && index < m_List.Count; ++i, ++index) { NetState ns = m_List[index] as NetState; if (ns == null) continue; Mobile m = ns.Mobile; Account a = ns.Account as Account; int offset = 140 + (i * 20); if (m == null) { if (RemoteAdmin.AdminNetwork.IsAuth(ns)) AddLabelCropped(12, offset, 81, 20, LabelHue, "(remote admin)"); else AddLabelCropped(12, offset, 81, 20, LabelHue, "(logging in)"); } else { AddLabelCropped(12, offset, 81, 20, GetHueFor(m), m.Name); } AddLabelCropped(95, offset, 81, 20, LabelHue, a == null ? "(no account)" : a.Username); AddLabelCropped(178, offset, 81, 20, LabelHue, m == null ? (a != null ? FormatAccessLevel(a.AccessLevel) : "") : FormatAccessLevel(m.AccessLevel)); AddLabelCropped(273, offset, 109, 20, LabelHue, ns.ToString()); if (a != null || m != null) AddButton(380, offset - 1, 0xFA5, 0xFA7, GetButtonID(4, index + 2), GumpButtonType.Reply, 0); } break; } case AdminGumpPage.ClientInfo: { Mobile m = state as Mobile; if (m == null) break; AddClientHeader(); AddHtml(10, 125, 400, 20, Color(Center("Information"), LabelColor32), false, false); int y = 146; AddLabel(20, y, LabelHue, "Name:"); AddLabel(200, y, GetHueFor(m), m.Name); y += 20; Account a = m.Account as Account; AddLabel(20, y, LabelHue, "Account:"); AddLabel(200, y, (a != null && a.Banned) ? RedHue : LabelHue, a == null ? "(no account)" : a.Username); AddButton(380, y, 0xFA5, 0xFA7, GetButtonID(7, 14), GumpButtonType.Reply, 0); y += 20; NetState ns = m.NetState; if (ns == null) { AddLabel(20, y, LabelHue, "Address:"); AddLabel(200, y, RedHue, "Offline"); y += 20; AddLabel(20, y, LabelHue, "Location:"); AddLabel(200, y, LabelHue, string.Format("{0} [{1}]", m.Location, m.Map)); y += 44; } else { AddLabel(20, y, LabelHue, "Address:"); AddLabel(200, y, GreenHue, ns.ToString()); y += 20; ClientVersion v = ns.Version; AddLabel(20, y, LabelHue, "Version:"); AddLabel(200, y, LabelHue, v == null ? "(null)" : v.ToString()); y += 20; AddLabel(20, y, LabelHue, "Location:"); AddLabel(200, y, LabelHue, string.Format("{0} [{1}]", m.Location, m.Map)); y += 24; } AddButtonLabeled(20, y, GetButtonID(7, 0), "Go to"); AddButtonLabeled(200, y, GetButtonID(7, 1), "Get"); y += 20; AddButtonLabeled(20, y, GetButtonID(7, 2), "Kick"); AddButtonLabeled(200, y, GetButtonID(7, 3), "Ban"); y += 20; AddButtonLabeled(20, y, GetButtonID(7, 4), "Properties"); AddButtonLabeled(200, y, GetButtonID(7, 5), "Skills"); y += 20; AddButtonLabeled(20, y, GetButtonID(7, 6), "Mortal"); AddButtonLabeled(200, y, GetButtonID(7, 7), "Immortal"); y += 20; AddButtonLabeled(20, y, GetButtonID(7, 8), "Squelch"); AddButtonLabeled(200, y, GetButtonID(7, 9), "Unsquelch"); y += 20; AddButtonLabeled(20, y, GetButtonID(7, 12), "Kill"); AddButtonLabeled(200, y, GetButtonID(7, 13), "Resurrect"); break; } case AdminGumpPage.Accounts_Shared: { if (m_List == null) m_List = GetAllSharedAccounts(); AddLabelCropped(12, 120, 60, 20, LabelHue, "Count"); AddLabelCropped(72, 120, 120, 20, LabelHue, "Address"); AddLabelCropped(192, 120, 180, 20, LabelHue, "Accounts"); if (listPage > 0) AddButton(375, 122, 0x15E3, 0x15E7, GetButtonID(1, 0), GumpButtonType.Reply, 0); else AddImage(375, 122, 0x25EA); if ((listPage + 1) * 12 < m_List.Count) AddButton(392, 122, 0x15E1, 0x15E5, GetButtonID(1, 1), GumpButtonType.Reply, 0); else AddImage(392, 122, 0x25E6); if (m_List.Count == 0) AddLabel(12, 140, LabelHue, "There are no accounts to display."); StringBuilder sb = new StringBuilder(); for (int i = 0, index = (listPage * 12); i < 12 && index >= 0 && index < m_List.Count; ++i, ++index) { DictionaryEntry de = (DictionaryEntry)m_List[index]; IPAddress ipAddr = (IPAddress)de.Key; ArrayList accts = (ArrayList)de.Value; int offset = 140 + (i * 20); AddLabelCropped(12, offset, 60, 20, LabelHue, accts.Count.ToString()); AddLabelCropped(72, offset, 120, 20, LabelHue, ipAddr.ToString()); if (sb.Length > 0) sb.Length = 0; for (int j = 0; j < accts.Count; ++j) { if (j > 0) sb.Append(", "); if (j < 4) { Account acct = (Account)accts[j]; sb.Append(acct.Username); } else { sb.Append("..."); break; } } AddLabelCropped(192, offset, 180, 20, LabelHue, sb.ToString()); AddButton(380, offset - 1, 0xFA5, 0xFA7, GetButtonID(5, index + 56), GumpButtonType.Reply, 0); } break; } case AdminGumpPage.Accounts: { if (m_List == null) { m_List = new ArrayList((ICollection)Accounts.GetAccounts()); m_List.Sort(AccountComparer.Instance); } ArrayList rads = (state as ArrayList); AddAccountHeader(); if (rads == null) AddLabelCropped(12, 120, 120, 20, LabelHue, "Name"); else AddLabelCropped(32, 120, 100, 20, LabelHue, "Name"); AddLabelCropped(132, 120, 120, 20, LabelHue, "Access Level"); AddLabelCropped(252, 120, 120, 20, LabelHue, "Status"); if (listPage > 0) AddButton(375, 122, 0x15E3, 0x15E7, GetButtonID(1, 0), GumpButtonType.Reply, 0); else AddImage(375, 122, 0x25EA); if ((listPage + 1) * 12 < m_List.Count) AddButton(392, 122, 0x15E1, 0x15E5, GetButtonID(1, 1), GumpButtonType.Reply, 0); else AddImage(392, 122, 0x25E6); if (m_List.Count == 0) AddLabel(12, 140, LabelHue, "There are no accounts to display."); if (rads != null && notice == null) { AddButtonLabeled(10, 390, GetButtonID(5, 27), "Ban marked"); AddButtonLabeled(10, 410, GetButtonID(5, 28), "Delete marked"); AddButtonLabeled(210, 390, GetButtonID(5, 29), "Mark all"); AddButtonLabeled(210, 410, GetButtonID(5, 35), "Unmark house owners"); } for (int i = 0, index = (listPage * 12); i < 12 && index >= 0 && index < m_List.Count; ++i, ++index) { Account a = m_List[index] as Account; if (a == null) continue; int offset = 140 + (i * 20); AccessLevel accessLevel; bool online; GetAccountInfo(a, out accessLevel, out online); if (rads == null) { AddLabelCropped(12, offset, 120, 20, LabelHue, a.Username); } else { AddCheck(10, offset, 0xD2, 0xD3, rads.Contains(a), index); AddLabelCropped(32, offset, 100, 20, LabelHue, a.Username); } AddLabelCropped(132, offset, 120, 20, LabelHue, FormatAccessLevel(accessLevel)); if (online) AddLabelCropped(252, offset, 120, 20, GreenHue, "Online"); else if (a.Banned) AddLabelCropped(252, offset, 120, 20, RedHue, "Banned"); else AddLabelCropped(252, offset, 120, 20, RedHue, "Offline"); AddButton(380, offset - 1, 0xFA5, 0xFA7, GetButtonID(5, index + 56), GumpButtonType.Reply, 0); } break; } case AdminGumpPage.AccountDetails: { AddPageButton(190, 10, GetButtonID(5, 0), "Information", AdminGumpPage.AccountDetails_Information, AdminGumpPage.AccountDetails_ChangeAccess, AdminGumpPage.AccountDetails_ChangePassword); AddPageButton(190, 30, GetButtonID(5, 1), "Characters", AdminGumpPage.AccountDetails_Characters); AddPageButton(190, 50, GetButtonID(5, 13), "Access", AdminGumpPage.AccountDetails_Access, AdminGumpPage.AccountDetails_Access_ClientIPs, AdminGumpPage.AccountDetails_Access_Restrictions); AddPageButton(190, 70, GetButtonID(5, 2), "Comments", AdminGumpPage.AccountDetails_Comments); AddPageButton(190, 90, GetButtonID(5, 3), "Tags", AdminGumpPage.AccountDetails_Tags); break; } case AdminGumpPage.AccountDetails_ChangePassword: { Account a = state as Account; if (a == null) break; AddHtml(10, 125, 400, 20, Color(Center("Change Password"), LabelColor32), false, false); AddLabel(20, 150, LabelHue, "Username:"); AddLabel(200, 150, LabelHue, a.Username); AddLabel(20, 180, LabelHue, "Password:"); AddTextField(200, 180, 160, 20, 0); AddLabel(20, 210, LabelHue, "Confirm:"); AddTextField(200, 210, 160, 20, 1); AddButtonLabeled(20, 240, GetButtonID(5, 12), "Submit Change"); goto case AdminGumpPage.AccountDetails; } case AdminGumpPage.AccountDetails_ChangeAccess: { Account a = state as Account; if (a == null) break; AddHtml(10, 125, 400, 20, Color(Center("Change Access Level"), LabelColor32), false, false); AddLabel(20, 150, LabelHue, "Username:"); AddLabel(200, 150, LabelHue, a.Username); AddLabel(20, 170, LabelHue, "Current Level:"); AddLabel(200, 170, LabelHue, FormatAccessLevel(a.AccessLevel)); AddButtonLabeled(20, 200, GetButtonID(5, 20), "Player"); AddButtonLabeled(20, 220, GetButtonID(5, 21), "Counselor"); AddButtonLabeled(20, 240, GetButtonID(5, 22), "Game Master"); AddButtonLabeled(20, 260, GetButtonID(5, 23), "Seer"); if (from.AccessLevel > AccessLevel.Administrator) { AddButtonLabeled(20, 280, GetButtonID(5, 24), "Administrator"); if (from.AccessLevel > AccessLevel.Developer) { AddButtonLabeled(20, 300, GetButtonID(5, 33), "Developer"); if (from.AccessLevel >= AccessLevel.Owner) AddButtonLabeled(20, 320, GetButtonID(5, 34), "Owner"); } } goto case AdminGumpPage.AccountDetails; } case AdminGumpPage.AccountDetails_Information: { Account a = state as Account; if (a == null) break; int charCount = 0; for (int i = 0; i < a.Length; ++i) { if (a[i] != null) ++charCount; } AddHtml(10, 125, 400, 20, Color(Center("Information"), LabelColor32), false, false); AddLabel(20, 150, LabelHue, "Username:"); AddLabel(200, 150, LabelHue, a.Username); AddLabel(20, 170, LabelHue, "Access Level:"); AddLabel(200, 170, LabelHue, FormatAccessLevel(a.AccessLevel)); AddLabel(20, 190, LabelHue, "Status:"); AddLabel(200, 190, a.Banned ? RedHue : GreenHue, a.Banned ? "Banned" : "Active"); DateTime banTime; TimeSpan banDuration; if (a.Banned && a.GetBanTags(out banTime, out banDuration)) { if (banDuration == TimeSpan.MaxValue) { AddLabel(250, 190, LabelHue, "(Infinite)"); } else if (banDuration == TimeSpan.Zero) { AddLabel(250, 190, LabelHue, "(Zero)"); } else { TimeSpan remaining = (DateTime.UtcNow - banTime); if (remaining < TimeSpan.Zero) remaining = TimeSpan.Zero; else if (remaining > banDuration) remaining = banDuration; double remMinutes = remaining.TotalMinutes; double totMinutes = banDuration.TotalMinutes; double perc = remMinutes / totMinutes; AddLabel(250, 190, LabelHue, string.Format("{0} [{1:F0}%]", FormatTimeSpan(banDuration), perc * 100)); } } else if (a.Banned) { AddLabel(250, 190, LabelHue, "(Unspecified)"); } AddLabel(20, 210, LabelHue, "Created:"); AddLabel(200, 210, LabelHue, a.Created.ToString()); AddLabel(20, 230, LabelHue, "Last Login:"); AddLabel(200, 230, LabelHue, a.LastLogin.ToString()); AddLabel(20, 250, LabelHue, "Character Count:"); AddLabel(200, 250, LabelHue, charCount.ToString()); AddLabel(20, 270, LabelHue, "Comment Count:"); AddLabel(200, 270, LabelHue, a.Comments.Count.ToString()); AddLabel(20, 290, LabelHue, "Tag Count:"); AddLabel(200, 290, LabelHue, a.Tags.Count.ToString()); AddButtonLabeled(20, 320, GetButtonID(5, 8), "Change Password"); AddButtonLabeled(200, 320, GetButtonID(5, 9), "Change Access Level"); if (!a.Banned) AddButtonLabeled(20, 350, GetButtonID(5, 10), "Ban Account"); else AddButtonLabeled(20, 350, GetButtonID(5, 11), "Unban Account"); AddButtonLabeled(200, 350, GetButtonID(5, 25), "Delete Account"); goto case AdminGumpPage.AccountDetails; } case AdminGumpPage.AccountDetails_Access: { Account a = state as Account; if (a == null) break; AddHtml(10, 125, 400, 20, Color(Center("Access"), LabelColor32), false, false); AddPageButton(20, 150, GetButtonID(5, 14), "View client addresses", AdminGumpPage.AccountDetails_Access_ClientIPs); AddPageButton(20, 170, GetButtonID(5, 15), "Manage restrictions", AdminGumpPage.AccountDetails_Access_Restrictions); goto case AdminGumpPage.AccountDetails; } case AdminGumpPage.AccountDetails_Access_ClientIPs: { Account a = state as Account; if (a == null) break; if (m_List == null) m_List = new ArrayList(a.LoginIPs); AddHtml(10, 195, 400, 20, Color(Center("Client Addresses"), LabelColor32), false, false); AddButtonLabeled(227, 225, GetButtonID(5, 16), "View all shared accounts"); AddButtonLabeled(227, 245, GetButtonID(5, 17), "Ban all shared accounts"); AddButtonLabeled(227, 265, GetButtonID(5, 18), "Firewall all addresses"); AddButtonLabeled(227, 285, GetButtonID(5, 36), "Clear all addresses"); AddHtml(225, 315, 180, 80, Color("List of IP addresses which have accessed this account.", LabelColor32), false, false); AddImageTiled(15, 219, 206, 156, 0xBBC); AddBlackAlpha(16, 220, 204, 154); AddHtml(18, 221, 114, 20, Color("IP Address", LabelColor32), false, false); if (listPage > 0) AddButton(184, 223, 0x15E3, 0x15E7, GetButtonID(1, 0), GumpButtonType.Reply, 0); else AddImage(184, 223, 0x25EA); if ((listPage + 1) * 6 < m_List.Count) AddButton(201, 223, 0x15E1, 0x15E5, GetButtonID(1, 1), GumpButtonType.Reply, 0); else AddImage(201, 223, 0x25E6); if (m_List.Count == 0) AddHtml(18, 243, 200, 60, Color("This account has not yet been accessed.", LabelColor32), false, false); for (int i = 0, index = (listPage * 6); i < 6 && index >= 0 && index < m_List.Count; ++i, ++index) { AddHtml(18, 243 + (i * 22), 114, 20, Color(m_List[index].ToString(), LabelColor32), false, false); AddButton(130, 242 + (i * 22), 0xFA2, 0xFA4, GetButtonID(8, index), GumpButtonType.Reply, 0); AddButton(160, 242 + (i * 22), 0xFA8, 0xFAA, GetButtonID(9, index), GumpButtonType.Reply, 0); AddButton(190, 242 + (i * 22), 0xFB1, 0xFB3, GetButtonID(10, index), GumpButtonType.Reply, 0); } goto case AdminGumpPage.AccountDetails_Access; } case AdminGumpPage.AccountDetails_Access_Restrictions: { Account a = state as Account; if (a == null) break; if (m_List == null) m_List = new ArrayList(a.IPRestrictions); AddHtml(10, 195, 400, 20, Color(Center("Address Restrictions"), LabelColor32), false, false); AddTextField(227, 225, 120, 20, 0); AddButtonLabeled(352, 225, GetButtonID(5, 19), "Add"); AddHtml(225, 255, 180, 120, Color("Any clients connecting from an address not in this list will be rejected. Or, if the list is empty, any client may connect.", LabelColor32), false, false); AddImageTiled(15, 219, 206, 156, 0xBBC); AddBlackAlpha(16, 220, 204, 154); AddHtml(18, 221, 114, 20, Color("IP Address", LabelColor32), false, false); if (listPage > 0) AddButton(184, 223, 0x15E3, 0x15E7, GetButtonID(1, 0), GumpButtonType.Reply, 0); else AddImage(184, 223, 0x25EA); if ((listPage + 1) * 6 < m_List.Count) AddButton(201, 223, 0x15E1, 0x15E5, GetButtonID(1, 1), GumpButtonType.Reply, 0); else AddImage(201, 223, 0x25E6); if (m_List.Count == 0) AddHtml(18, 243, 200, 60, Color("There are no addresses in this list.", LabelColor32), false, false); for (int i = 0, index = (listPage * 6); i < 6 && index >= 0 && index < m_List.Count; ++i, ++index) { AddHtml(18, 243 + (i * 22), 114, 20, Color(m_List[index].ToString(), LabelColor32), false, false); AddButton(190, 242 + (i * 22), 0xFB1, 0xFB3, GetButtonID(8, index), GumpButtonType.Reply, 0); } goto case AdminGumpPage.AccountDetails_Access; } case AdminGumpPage.AccountDetails_Characters: { Account a = state as Account; if (a == null) break; AddHtml(10, 125, 400, 20, Color(Center("Characters"), LabelColor32), false, false); AddLabelCropped(12, 150, 120, 20, LabelHue, "Name"); AddLabelCropped(132, 150, 120, 20, LabelHue, "Access Level"); AddLabelCropped(252, 150, 120, 20, LabelHue, "Status"); int index = 0; for (int i = 0; i < a.Length; ++i) { Mobile m = a[i]; if (m == null) continue; int offset = 170 + (index * 20); AddLabelCropped(12, offset, 120, 20, GetHueFor(m), m.Name); AddLabelCropped(132, offset, 120, 20, LabelHue, FormatAccessLevel(m.AccessLevel)); if (m.NetState != null) AddLabelCropped(252, offset, 120, 20, GreenHue, "Online"); else AddLabelCropped(252, offset, 120, 20, RedHue, "Offline"); AddButton(380, offset - 1, 0xFA5, 0xFA7, GetButtonID(5, i + 50), GumpButtonType.Reply, 0); ++index; } if (index == 0) AddLabel(12, 170, LabelHue, "The character list is empty."); goto case AdminGumpPage.AccountDetails; } case AdminGumpPage.AccountDetails_Comments: { Account a = state as Account; if (a == null) break; AddHtml(10, 125, 400, 20, Color(Center("Comments"), LabelColor32), false, false); AddButtonLabeled(20, 150, GetButtonID(5, 4), "Add Comment"); StringBuilder sb = new StringBuilder(); if (a.Comments.Count == 0) sb.Append("There are no comments for this account."); for (int i = 0; i < a.Comments.Count; ++i) { if (i > 0) sb.Append("

"); AccountComment c = a.Comments[i]; sb.AppendFormat("[{0} on {1}]
{2}", c.AddedBy, c.LastModified, c.Content); } AddHtml(20, 180, 380, 190, sb.ToString(), true, true); goto case AdminGumpPage.AccountDetails; } case AdminGumpPage.AccountDetails_Tags: { Account a = state as Account; if (a == null) break; AddHtml(10, 125, 400, 20, Color(Center("Tags"), LabelColor32), false, false); AddButtonLabeled(20, 150, GetButtonID(5, 5), "Add Tag"); StringBuilder sb = new StringBuilder(); if (a.Tags.Count == 0) sb.Append("There are no tags for this account."); for (int i = 0; i < a.Tags.Count; ++i) { if (i > 0) sb.Append("
"); AccountTag tag = a.Tags[i]; sb.AppendFormat("{0} = {1}", tag.Name, tag.Value); } AddHtml(20, 180, 380, 190, sb.ToString(), true, true); goto case AdminGumpPage.AccountDetails; } case AdminGumpPage.Firewall: { AddFirewallHeader(); if (m_List == null) m_List = new ArrayList(Firewall.List); AddLabelCropped(12, 120, 358, 20, LabelHue, "IP Address"); if (listPage > 0) AddButton(375, 122, 0x15E3, 0x15E7, GetButtonID(1, 0), GumpButtonType.Reply, 0); else AddImage(375, 122, 0x25EA); if ((listPage + 1) * 12 < m_List.Count) AddButton(392, 122, 0x15E1, 0x15E5, GetButtonID(1, 1), GumpButtonType.Reply, 0); else AddImage(392, 122, 0x25E6); if (m_List.Count == 0) AddLabel(12, 140, LabelHue, "The firewall list is empty."); for (int i = 0, index = (listPage * 12); i < 12 && index >= 0 && index < m_List.Count; ++i, ++index) { object obj = m_List[index]; if (!(obj is Firewall.IFirewallEntry)) break; int offset = 140 + (i * 20); AddLabelCropped(12, offset, 358, 20, LabelHue, obj.ToString()); AddButton(380, offset - 1, 0xFA5, 0xFA7, GetButtonID(6, index + 4), GumpButtonType.Reply, 0); } break; } case AdminGumpPage.FirewallInfo: { AddFirewallHeader(); if (!(state is Firewall.IFirewallEntry)) break; AddHtml(10, 125, 400, 20, Color(Center(state.ToString()), LabelColor32), false, false); AddButtonLabeled(20, 150, GetButtonID(6, 3), "Remove"); AddHtml(10, 175, 400, 20, Color(Center("Potentially Affected Accounts"), LabelColor32), false, false); if (m_List == null) { m_List = new ArrayList(); foreach (Account acct in Accounts.GetAccounts()) { IPAddress[] loginList = acct.LoginIPs; bool contains = false; for (int i = 0; !contains && i < loginList.Length; ++i) { if (((Firewall.IFirewallEntry)state).IsBlocked(loginList[i])) { m_List.Add(acct); break; } } } m_List.Sort(AccountComparer.Instance); } if (listPage > 0) AddButton(375, 177, 0x15E3, 0x15E7, GetButtonID(1, 0), GumpButtonType.Reply, 0); else AddImage(375, 177, 0x25EA); if ((listPage + 1) * 12 < m_List.Count) AddButton(392, 177, 0x15E1, 0x15E5, GetButtonID(1, 1), GumpButtonType.Reply, 0); else AddImage(392, 177, 0x25E6); if (m_List.Count == 0) AddLabelCropped(12, 200, 398, 20, LabelHue, "No accounts found."); for (int i = 0, index = (listPage * 9); i < 9 && index >= 0 && index < m_List.Count; ++i, ++index) { Account a = m_List[index] as Account; if (a == null) continue; int offset = 200 + (i * 20); AccessLevel accessLevel; bool online; GetAccountInfo(a, out accessLevel, out online); AddLabelCropped(12, offset, 120, 20, LabelHue, a.Username); AddLabelCropped(132, offset, 120, 20, LabelHue, FormatAccessLevel(accessLevel)); if (online) AddLabelCropped(252, offset, 120, 20, GreenHue, "Online"); else if (a.Banned) AddLabelCropped(252, offset, 120, 20, RedHue, "Banned"); else AddLabelCropped(252, offset, 120, 20, RedHue, "Offline"); AddButton(380, offset - 1, 0xFA5, 0xFA7, GetButtonID(5, index + 56), GumpButtonType.Reply, 0); } break; } } } public void AddTextField(int x, int y, int width, int height, int index) { AddBackground(x - 2, y - 2, width + 4, height + 4, 0x2486); AddTextEntry(x + 2, y + 2, width - 4, height - 4, 0, index, ""); } public void AddClientHeader() { AddTextField(200, 20, 200, 20, 0); AddButtonLabeled(200, 50, GetButtonID(4, 0), "Search For Name"); AddButtonLabeled(200, 80, GetButtonID(4, 1), "Search For IP Address"); } public void AddAccountHeader() { AddPage(1); AddLabel(200, 20, LabelHue, "Name:"); AddTextField(250, 20, 150, 20, 0); AddLabel(200, 50, LabelHue, "Pass:"); AddTextField(250, 50, 150, 20, 1); AddButtonLabeled(200, 80, GetButtonID(5, 6), "Add"); AddButtonLabeled(290, 80, GetButtonID(5, 7), "Search"); AddButton(384, 84, 0x15E1, 0x15E5, 0, GumpButtonType.Page, 2); AddPage(2); AddButtonLabeled(200, 10, GetButtonID(5, 31), "View All: Inactive"); AddButtonLabeled(200, 30, GetButtonID(5, 32), "View All: Banned"); AddButtonLabeled(200, 50, GetButtonID(5, 26), "View All: Shared"); AddButtonLabeled(200, 70, GetButtonID(5, 33), "View All: Empty"); AddButtonLabeled(200, 90, GetButtonID(5, 30), "View All: TotalGameTime"); AddButton(384, 84, 0x15E1, 0x15E5, 0, GumpButtonType.Page, 1); AddPage(0); } public void AddFirewallHeader() { AddTextField(200, 20, 200, 20, 0); AddButtonLabeled(320, 50, GetButtonID(6, 0), "Search"); AddButtonLabeled(200, 50, GetButtonID(6, 1), "Add (Input)"); AddButtonLabeled(200, 80, GetButtonID(6, 2), "Add (Target)"); } private static ArrayList GetAllSharedAccounts() { Hashtable table = new Hashtable(); ArrayList list; foreach (Account acct in Accounts.GetAccounts()) { IPAddress[] theirAddresses = acct.LoginIPs; for (int i = 0; i < theirAddresses.Length; ++i) { list = (ArrayList)table[theirAddresses[i]]; if (list == null) table[theirAddresses[i]] = list = new ArrayList(); list.Add(acct); } } list = new ArrayList(table); for (int i = 0; i < list.Count; ++i) { DictionaryEntry de = (DictionaryEntry)list[i]; ArrayList accts = (ArrayList)de.Value; if (accts.Count == 1) list.RemoveAt(i--); else accts.Sort(AccountComparer.Instance); } list.Sort(SharedAccountComparer.Instance); return list; } private class SharedAccountComparer : IComparer { public static readonly IComparer Instance = new SharedAccountComparer(); public int Compare(object x, object y) { DictionaryEntry a = (DictionaryEntry)x; DictionaryEntry b = (DictionaryEntry)y; ArrayList aList = (ArrayList)a.Value; ArrayList bList = (ArrayList)b.Value; return bList.Count - aList.Count; } } private static ArrayList GetSharedAccounts(IPAddress ipAddress) { ArrayList list = new ArrayList(); foreach (Account acct in Accounts.GetAccounts()) { IPAddress[] theirAddresses = acct.LoginIPs; bool contains = false; for (int i = 0; !contains && i < theirAddresses.Length; ++i) contains = ipAddress.Equals(theirAddresses[i]); if (contains) list.Add(acct); } list.Sort(AccountComparer.Instance); return list; } private static ArrayList GetSharedAccounts(IPAddress[] ipAddresses) { ArrayList list = new ArrayList(); foreach (Account acct in Accounts.GetAccounts()) { IPAddress[] theirAddresses = acct.LoginIPs; bool contains = false; for (int i = 0; !contains && i < theirAddresses.Length; ++i) { IPAddress check = theirAddresses[i]; for (int j = 0; !contains && j < ipAddresses.Length; ++j) contains = check.Equals(ipAddresses[j]); } if (contains) list.Add(acct); } list.Sort(AccountComparer.Instance); return list; } public static void BanShared_Callback(Mobile from, bool okay, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; string notice; ArrayList list = null; if (okay) { Account a = (Account)state; list = GetSharedAccounts(a.LoginIPs); for (int i = 0; i < list.Count; ++i) { ((Account)list[i]).SetUnspecifiedBan(from); ((Account)list[i]).Banned = true; } notice = "All addresses in the list have been banned."; } else { notice = "You have chosen not to ban all shared accounts."; } from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, state)); if (okay) from.SendGump(new BanDurationGump(list)); } public static void AccountDelete_Callback(Mobile from, bool okay, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; if (okay) { Account a = (Account)state; CommandLogging.WriteLine(from, "{0} {1} deleting account {2}", from.AccessLevel, CommandLogging.Format(from), a.Username); a.Delete(); from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, null, string.Format("{0} : The account has been deleted.", a.Username), null)); } else { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "You have chosen not to delete the account.", state)); } } public static void ResendGump_Callback(Mobile from, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; object[] states = (object[])state; ArrayList list = (ArrayList)states[0]; ArrayList rads = (ArrayList)states[1]; int page = (int)states[2]; from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, page, list, null, rads)); } public static void Marked_Callback(Mobile from, bool okay, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; object[] states = (object[])state; bool ban = (bool)states[0]; ArrayList list = (ArrayList)states[1]; ArrayList rads = (ArrayList)states[2]; int page = (int)states[3]; if (okay) { if (!ban) NetState.Pause(); for (int i = 0; i < rads.Count; ++i) { Account acct = (Account)rads[i]; if (ban) { CommandLogging.WriteLine(from, "{0} {1} banning account {2}", from.AccessLevel, CommandLogging.Format(from), acct.Username); acct.SetUnspecifiedBan(from); acct.Banned = true; } else { CommandLogging.WriteLine(from, "{0} {1} deleting account {2}", from.AccessLevel, CommandLogging.Format(from), acct.Username); acct.Delete(); rads.RemoveAt(i--); list.Remove(acct); } } if (!ban) NetState.Resume(); from.SendGump(new NoticeGump(1060637, 30720, string.Format("You have {0} the account{1}.", ban ? "banned" : "deleted", rads.Count == 1 ? "" : "s"), 0xFFC000, 420, 280, ResendGump_Callback, new object[] { list, rads, ban ? page : 0 })); if (ban) from.SendGump(new BanDurationGump(rads)); } else { from.SendGump(new NoticeGump(1060637, 30720, string.Format("You have chosen not to {0} the account{1}.", ban ? "ban" : "delete", rads.Count == 1 ? "" : "s"), 0xFFC000, 420, 280, ResendGump_Callback, new object[] { list, rads, page })); } } public static void FirewallShared_Callback(Mobile from, bool okay, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; string notice; if (okay) { Account a = (Account)state; for (int i = 0; i < a.LoginIPs.Length; ++i) Firewall.Add(a.LoginIPs[i]); notice = "All addresses in the list have been firewalled."; } else { notice = "You have chosen not to firewall all addresses."; } from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, state)); } public static void Firewall_Callback(Mobile from, bool okay, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; object[] states = (object[])state; Account a = (Account)states[0]; object toFirewall = states[1]; string notice; if (okay) { Firewall.Add(toFirewall); notice = string.Format("{0} : Added to firewall.", toFirewall); } else { notice = "You have chosen not to firewall the address."; } from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, a)); } public static void RemoveLoginIP_Callback(Mobile from, bool okay, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; object[] states = (object[])state; Account a = (Account)states[0]; IPAddress ip = (IPAddress)states[1]; string notice; if (okay) { IPAddress[] ips = a.LoginIPs; if (ips.Length != 0 && ip == ips[0] && AccountHandler.IPTable.ContainsKey(ips[0])) --AccountHandler.IPTable[ip]; List newList = new List(ips); newList.Remove(ip); a.LoginIPs = newList.ToArray(); notice = string.Format("{0} : Removed address.", ip); } else { notice = "You have chosen not to remove the address."; } from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, a)); } public static void RemoveLoginIPs_Callback(Mobile from, bool okay, object state) { if (from.AccessLevel < AccessLevel.Administrator) return; Account a = (Account)state; string notice; if (okay) { IPAddress[] ips = a.LoginIPs; if (ips.Length != 0 && AccountHandler.IPTable.ContainsKey(ips[0])) --AccountHandler.IPTable[ips[0]]; a.LoginIPs = new IPAddress[0]; notice = "All addresses in the list have been removed."; } else { notice = "You have chosen not to clear all addresses."; } from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, a)); } public override void OnResponse(NetState sender, RelayInfo info) { int val = info.ButtonID - 1; if (val < 0) return; Mobile from = m_From; if (from.AccessLevel < AccessLevel.Administrator) return; if (m_PageType == AdminGumpPage.Accounts) { ArrayList list = m_List; ArrayList rads = m_State as ArrayList; if (list != null && rads != null) { for (int i = 0, v = m_ListPage * 12; i < 12 && v < list.Count; ++i, ++v) { object obj = list[v]; if (info.IsSwitched(v)) { if (!rads.Contains(obj)) rads.Add(obj); } else if (rads.Contains(obj)) { rads.Remove(obj); } } } } int type = val % 11; int index = val / 11; switch (type) { case 0: { AdminGumpPage page; switch (index) { case 0: page = AdminGumpPage.Information_General; break; case 1: page = AdminGumpPage.Administer; break; case 2: page = AdminGumpPage.Clients; break; case 3: page = AdminGumpPage.Accounts; break; case 4: page = AdminGumpPage.Firewall; break; case 5: page = AdminGumpPage.Information_Perf; break; default: return; } from.SendGump(new AdminGump(from, page, 0, null, null, null)); break; } case 1: { switch (index) { case 0: { if (m_List != null && m_ListPage > 0) from.SendGump(new AdminGump(from, m_PageType, m_ListPage - 1, m_List, null, m_State)); break; } case 1: { if (m_List != null /*&& (m_ListPage + 1) * 12 < m_List.Count*/) from.SendGump(new AdminGump(from, m_PageType, m_ListPage + 1, m_List, null, m_State)); break; } } break; } case 3: { string notice = null; AdminGumpPage page = AdminGumpPage.Administer; if (index >= 600) page = AdminGumpPage.Administer_Maintenance; else if (index >= 500) page = AdminGumpPage.Administer_Access_Lockdown; else if (index >= 400) page = AdminGumpPage.Administer_Commands; else if (index >= 300) page = AdminGumpPage.Administer_Access; else if (index >= 200) page = AdminGumpPage.Administer_Server; else if (index >= 100) page = AdminGumpPage.Administer_WorldBuilding; switch (index) { case 0: page = AdminGumpPage.Administer_WorldBuilding; break; case 1: page = AdminGumpPage.Administer_Server; break; case 2: page = AdminGumpPage.Administer_Access; break; case 3: page = AdminGumpPage.Administer_Commands; break; case 4: page = AdminGumpPage.Administer_Maintenance; break; case 101: InvokeCommand("CreateWorld nogump"); notice = "The world has been created."; break; case 102: InvokeCommand("DeleteWorld nogump"); notice = "The world has been deleted."; break; case 103: InvokeCommand("RecreateWorld nogump"); notice = "The world has been recreated."; break; case 110: InvokeCommand("Freeze"); notice = "Target bounding points."; break; case 120: InvokeCommand("Unfreeze"); notice = "Target bounding points."; break; case 200: InvokeCommand("Save"); notice = "The world has been saved."; break; case 201: Shutdown(false, true); break; case 202: Shutdown(false, false); break; case 203: Shutdown(true, true); break; case 204: Shutdown(true, false); break; case 210: case 211: { TextRelay relay = info.GetTextEntry(0); string text = (relay == null ? null : relay.Text.Trim()); if (string.IsNullOrEmpty(text)) { notice = "You must enter text to broadcast it."; } else { notice = "Your message has been broadcasted."; InvokeCommand(string.Format("{0} {1}", index == 210 ? "BC" : "SM", text)); } break; } case 300: InvokeCommand("Kick"); notice = "Target the player to kick."; break; case 301: InvokeCommand("Ban"); notice = "Target the player to ban."; break; case 302: InvokeCommand("Firewall"); notice = "Target the player to firewall."; break; case 303: page = AdminGumpPage.Administer_Access_Lockdown; break; case 310: InvokeCommand("Set AccessLevel Player"); notice = "Target the player to change their access level. (Player)"; break; case 311: InvokeCommand("Set AccessLevel Counselor"); notice = "Target the player to change their access level. (Counselor)"; break; case 312: InvokeCommand("Set AccessLevel GameMaster"); notice = "Target the player to change their access level. (Game Master)"; break; case 313: InvokeCommand("Set AccessLevel Seer"); notice = "Target the player to change their access level. (Seer)"; break; case 314: { if (from.AccessLevel > AccessLevel.Administrator) { InvokeCommand("Set AccessLevel Administrator"); notice = "Target the player to change their access level. (Administrator)"; } break; } case 315: { if (from.AccessLevel > AccessLevel.Developer) { InvokeCommand("Set AccessLevel Developer"); notice = "Target the player to change their access level. (Developer)"; } break; } case 316: { if (from.AccessLevel >= AccessLevel.Owner) { InvokeCommand("Set AccessLevel Owner"); notice = "Target the player to change their access level. (Owner)"; } break; } case 400: notice = "Enter search terms to add objects."; break; case 401: InvokeCommand("Remove"); notice = "Target the item or mobile to remove."; break; case 402: InvokeCommand("Dupe"); notice = "Target the item to dupe."; break; case 403: InvokeCommand("DupeInBag"); notice = "Target the item to dupe. The item will be duped at it's current location."; break; case 404: InvokeCommand("Props"); notice = "Target the item or mobile to inspect."; break; case 405: InvokeCommand("Skills"); notice = "Target a mobile to view their skills."; break; case 406: InvokeCommand("Set Blessed False"); notice = "Target the mobile to make mortal."; break; case 407: InvokeCommand("Set Blessed True"); notice = "Target the mobile to make immortal."; break; case 408: InvokeCommand("Set Squelched True"); notice = "Target the mobile to squelch."; break; case 409: InvokeCommand("Set Squelched False"); notice = "Target the mobile to unsquelch."; break; case 410: InvokeCommand("Set Frozen True"); notice = "Target the mobile to freeze."; break; case 411: InvokeCommand("Set Frozen False"); notice = "Target the mobile to unfreeze."; break; case 412: InvokeCommand("Set Hidden True"); notice = "Target the mobile to hide."; break; case 413: InvokeCommand("Set Hidden False"); notice = "Target the mobile to unhide."; break; case 414: InvokeCommand("Kill"); notice = "Target the mobile to kill."; break; case 415: InvokeCommand("Resurrect"); notice = "Target the mobile to resurrect."; break; case 416: InvokeCommand("Move"); notice = "Target the item or mobile to move."; break; case 417: InvokeCommand("Wipe"); notice = "Target bounding points."; break; case 418: InvokeCommand("Tele"); notice = "Choose your destination."; break; case 419: InvokeCommand("Multi Tele"); notice = "Choose your destination."; break; case 500: case 501: case 502: case 503: case 504: { AccountHandler.LockdownLevel = (AccessLevel)(index - 500); if (AccountHandler.LockdownLevel > AccessLevel.VIP) notice = "The lockdown level has been changed."; else notice = "The server is now accessible to everyone."; break; } case 510: { AccessLevel level = AccountHandler.LockdownLevel; if (level > AccessLevel.VIP) { List clients = NetState.Instances; int count = 0; for (int i = 0; i < clients.Count; ++i) { NetState ns = clients[i]; IAccount a = ns.Account; if (a == null) continue; bool hasAccess = false; if (a.AccessLevel >= level) { hasAccess = true; } else { for (int j = 0; !hasAccess && j < a.Length; ++j) { Mobile m = a[j]; if (m != null && m.AccessLevel >= level) hasAccess = true; } } if (!hasAccess) { ns.Dispose(); ++count; } } if (count == 0) notice = "Nobody without access was found to disconnect."; else notice = string.Format("Number of players disconnected: {0}", count); } else { notice = "The server is not currently locked down."; } break; } case 600: InvokeCommand("RebuildCategorization"); notice = "Categorization menu has been regenerated. The server should be restarted."; break; case 601: InvokeCommand("DocGen"); notice = "Documentation has been generated."; break; case 602: InvokeCommand("GenBounds"); notice = "Bounds.bin rebuild. Restart server to take effect."; break; case 604: InvokeCommand("DumpTimers"); notice = "Timers dumped."; break; case 605: InvokeCommand("CountObjects"); notice = "Objects counted."; break; case 606: InvokeCommand("ProfileWorld"); notice = "World profiled."; break; case 607: InvokeCommand("WriteProfiles"); notice = "Profiles written."; break; case 608: InvokeCommand("TraceInternal"); notice = "Tracing completed."; break; case 609: InvokeCommand("TraceExpanded"); notice = "Tracing completed."; break; case 610: InvokeCommand("SetProfiles"); notice = "Profiles toggled. Use with caution. This increases server load."; break; } from.SendGump(new AdminGump(from, page, 0, null, notice, null)); switch (index) { case 400: InvokeCommand("Add"); break; case 111: InvokeCommand("FreezeWorld"); break; case 112: InvokeCommand("FreezeMap"); break; case 121: InvokeCommand("UnfreezeWorld"); break; case 122: InvokeCommand("UnfreezeMap"); break; } break; } case 4: { switch (index) { case 0: case 1: { bool forName = (index == 0); ArrayList results = new ArrayList(); TextRelay matchEntry = info.GetTextEntry(0); string match = (matchEntry == null ? null : matchEntry.Text.Trim().ToLower()); string notice = null; if (string.IsNullOrEmpty(match)) { notice = string.Format("You must enter {0} to search.", forName ? "a name" : "an ip address"); } else { List instances = NetState.Instances; for (int i = 0; i < instances.Count; ++i) { NetState ns = instances[i]; bool isMatch; if (forName) { Mobile m = ns.Mobile; IAccount a = ns.Account; isMatch = (m != null && m.Name.ToLower().IndexOf(match) >= 0) || (a != null && a.Username.ToLower().IndexOf(match) >= 0); } else { isMatch = (ns.ToString().IndexOf(match) >= 0); } if (isMatch) results.Add(ns); } results.Sort(NetStateComparer.Instance); } if (results.Count == 1) { NetState ns = (NetState)results[0]; object state = ns.Mobile; if (state == null) state = ns.Account; if (state is Mobile) from.SendGump(new AdminGump(from, AdminGumpPage.ClientInfo, 0, null, "One match found.", state)); else if (state is Account) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "One match found.", state)); else from.SendGump(new AdminGump(from, AdminGumpPage.Clients, 0, results, "One match found.", null)); } else { from.SendGump(new AdminGump(from, AdminGumpPage.Clients, 0, results, notice == null ? (results.Count == 0 ? "Nothing matched your search terms." : null) : notice, null)); } break; } default: { index -= 2; if (m_List != null && index < m_List.Count) { NetState ns = m_List[index] as NetState; if (ns == null) break; Mobile m = ns.Mobile; Account a = ns.Account as Account; if (m != null) from.SendGump(new AdminGump(from, AdminGumpPage.ClientInfo, 0, null, null, m)); else if (a != null) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, null, a)); } break; } } break; } case 5: { switch (index) { case 0: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, null, m_State)); break; case 1: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Characters, 0, null, null, m_State)); break; case 2: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Comments, 0, null, null, m_State)); break; case 3: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Tags, 0, null, null, m_State)); break; case 13: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access, 0, null, null, m_State)); break; case 14: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, null, m_State)); break; case 15: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_Restrictions, 0, null, null, m_State)); break; case 4: from.Prompt = new AddCommentPrompt(m_State as Account); from.SendMessage("Enter the new account comment."); break; case 5: from.Prompt = new AddTagNamePrompt(m_State as Account); from.SendMessage("Enter the new tag name."); break; case 6: { TextRelay unEntry = info.GetTextEntry(0); TextRelay pwEntry = info.GetTextEntry(1); string un = (unEntry == null ? null : unEntry.Text.Trim()); string pw = (pwEntry == null ? null : pwEntry.Text.Trim()); Account dispAccount = null; string notice; if (string.IsNullOrEmpty(un)) { notice = "You must enter a username to add an account."; } else if (string.IsNullOrEmpty(pw)) { notice = "You must enter a password to add an account."; } else { IAccount account = Accounts.GetAccount(un); if (account != null) { notice = "There is already an account with that username."; } else { dispAccount = new Account(un, pw); notice = string.Format("{0} : Account added.", un); CommandLogging.WriteLine(from, "{0} {1} adding new account: {2}", from.AccessLevel, CommandLogging.Format(from), un); } } from.SendGump(new AdminGump(from, dispAccount != null ? AdminGumpPage.AccountDetails_Information : m_PageType, m_ListPage, m_List, notice, dispAccount != null ? dispAccount : m_State)); break; } case 7: { ArrayList results; TextRelay matchEntry = info.GetTextEntry(0); string match = (matchEntry == null ? null : matchEntry.Text.Trim().ToLower()); string notice = null; if (string.IsNullOrEmpty(match)) { results = new ArrayList((ICollection)Accounts.GetAccounts()); results.Sort(AccountComparer.Instance); //notice = "You must enter a username to search."; } else { results = new ArrayList(); foreach (Account check in Accounts.GetAccounts()) { if (check.Username.ToLower().IndexOf(match) >= 0) results.Add(check); } results.Sort(AccountComparer.Instance); } if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "One match found.", results[0])); else from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, results, notice == null ? (results.Count == 0 ? "Nothing matched your search terms." : null) : notice, new ArrayList())); break; } case 8: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_ChangePassword, 0, null, null, m_State)); break; case 9: from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_ChangeAccess, 0, null, null, m_State)); break; case 10: case 11: { Account a = m_State as Account; if (a == null) break; a.SetUnspecifiedBan(from); a.Banned = (index == 10); CommandLogging.WriteLine(from, "{0} {1} {3} account {2}", from.AccessLevel, CommandLogging.Format(from), a.Username, a.Banned ? "banning" : "unbanning"); from.SendGump(new AdminGump(from, m_PageType, m_ListPage, m_List, string.Format("The account has been {0}.", a.Banned ? "banned" : "unbanned"), m_State)); if (index == 10) from.SendGump(new BanDurationGump(a)); break; } case 12: { Account a = m_State as Account; if (a == null) break; TextRelay passwordEntry = info.GetTextEntry(0); TextRelay confirmEntry = info.GetTextEntry(1); string password = (passwordEntry == null ? null : passwordEntry.Text.Trim()); string confirm = (confirmEntry == null ? null : confirmEntry.Text.Trim()); string notice; AdminGumpPage page = AdminGumpPage.AccountDetails_ChangePassword; if (string.IsNullOrEmpty(password)) { notice = "You must enter the password."; } else if (confirm != password) { notice = "You must confirm the password. That field must precisely match the password field."; } else { notice = "The password has been changed."; a.SetPassword(password); page = AdminGumpPage.AccountDetails_Information; CommandLogging.WriteLine(from, "{0} {1} changing password of account {2}", from.AccessLevel, CommandLogging.Format(from), a.Username); } from.SendGump(new AdminGump(from, page, 0, null, notice, m_State)); break; } case 16: // view shared { Account a = m_State as Account; if (a == null) break; ArrayList list = GetSharedAccounts(a.LoginIPs); if (list.Count > 1 || (list.Count == 1 && !list.Contains(a))) { from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, list, null, new ArrayList())); } else if (a.LoginIPs.Length > 0) { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "There are no other accounts which share an address with this one.", m_State)); } else { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "This account has not yet been accessed.", m_State)); } break; } case 17: // ban shared { Account a = m_State as Account; if (a == null) break; ArrayList list = GetSharedAccounts(a.LoginIPs); if (list.Count > 0) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("You are about to ban {0} account{1}. Do you wish to continue?", list.Count, list.Count != 1 ? "s" : ""); for (int i = 0; i < list.Count; ++i) sb.AppendFormat("
- {0}", ((Account)list[i]).Username); from.SendGump(new WarningGump(1060635, 30720, sb.ToString(), 0xFFC000, 420, 400, BanShared_Callback, a)); } else if (a.LoginIPs.Length > 0) { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "There are no accounts which share an address with this one.", m_State)); } else { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "This account has not yet been accessed.", m_State)); } break; } case 18: // firewall all { Account a = m_State as Account; if (a == null) break; if (a.LoginIPs.Length > 0) { from.SendGump(new WarningGump(1060635, 30720, string.Format("You are about to firewall {0} address{1}. Do you wish to continue?", a.LoginIPs.Length, a.LoginIPs.Length != 1 ? "s" : ""), 0xFFC000, 420, 400, FirewallShared_Callback, a)); } else { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "This account has not yet been accessed.", m_State)); } break; } case 19: // add { Account a = m_State as Account; if (a == null) break; TextRelay entry = info.GetTextEntry(0); string ip = (entry == null ? null : entry.Text.Trim()); string notice; if (string.IsNullOrEmpty(ip)) { notice = "You must enter an address to add."; } else { string[] list = a.IPRestrictions; bool contains = false; for (int i = 0; !contains && i < list.Length; ++i) contains = (list[i] == ip); if (contains) { notice = "That address is already contained in the list."; } else { string[] newList = new string[list.Length + 1]; for (int i = 0; i < list.Length; ++i) newList[i] = list[i]; newList[list.Length] = ip; a.IPRestrictions = newList; notice = string.Format("{0} : Added to restriction list.", ip); } } from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_Restrictions, 0, null, notice, m_State)); break; } case 20: // Change access level case 21: case 22: case 23: case 24: { Account a = m_State as Account; if (a == null) break; AccessLevel newLevel; switch (index) { default: case 20: newLevel = AccessLevel.Player; break; case 21: newLevel = AccessLevel.Counselor; break; case 22: newLevel = AccessLevel.GameMaster; break; case 23: newLevel = AccessLevel.Seer; break; case 24: newLevel = AccessLevel.Administrator; break; case 33: newLevel = AccessLevel.Developer; break; case 34: newLevel = AccessLevel.Owner; break; } if (newLevel < from.AccessLevel || from.AccessLevel == AccessLevel.Owner) { a.AccessLevel = newLevel; CommandLogging.WriteLine(from, "{0} {1} changing access level of account {2} to {3}", from.AccessLevel, CommandLogging.Format(from), a.Username, a.AccessLevel); from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "The access level has been changed.", m_State)); } break; } case 25: { Account a = m_State as Account; if (a == null) break; from.SendGump(new WarningGump(1060635, 30720, string.Format("
Account of {0}

You are about to permanently delete the account. Likewise, all characters on the account will be deleted, including equiped, inventory, and banked items. Any houses tied to the account will be demolished.

Do you wish to continue?", a.Username), 0xFFC000, 420, 280, AccountDelete_Callback, m_State)); break; } case 26: // View all shared accounts { from.SendGump(new AdminGump(from, AdminGumpPage.Accounts_Shared, 0, null, null, null)); break; } case 27: // Ban marked { ArrayList list = m_List; ArrayList rads = m_State as ArrayList; if (list == null || rads == null) break; if (rads.Count > 0) from.SendGump(new WarningGump(1060635, 30720, string.Format("You are about to ban {0} marked account{1}. Be cautioned, the only way to reverse this is by hand--manually unbanning each account.

Do you wish to continue?", rads.Count, rads.Count == 1 ? "" : "s"), 0xFFC000, 420, 280, Marked_Callback, new object[] { true, list, rads, m_ListPage })); else from.SendGump(new NoticeGump(1060637, 30720, "You have not yet marked any accounts. Place a check mark next to the accounts you wish to ban and then try again.", 0xFFC000, 420, 280, ResendGump_Callback, new object[] { list, rads, m_ListPage })); break; } case 28: // Delete marked { ArrayList list = m_List; ArrayList rads = m_State as ArrayList; if (list == null || rads == null) break; if (rads.Count > 0) from.SendGump(new WarningGump(1060635, 30720, string.Format("You are about to permanently delete {0} marked account{1}. Likewise, all characters on the account{1} will be deleted, including equiped, inventory, and banked items. Any houses tied to the account{1} will be demolished.

Do you wish to continue?", rads.Count, rads.Count == 1 ? "" : "s"), 0xFFC000, 420, 280, Marked_Callback, new object[] { false, list, rads, m_ListPage })); else from.SendGump(new NoticeGump(1060637, 30720, "You have not yet marked any accounts. Place a check mark next to the accounts you wish to ban and then try again.", 0xFFC000, 420, 280, ResendGump_Callback, new object[] { list, rads, m_ListPage })); break; } case 29: // Mark all { ArrayList list = m_List; ArrayList rads = m_State as ArrayList; if (list == null || rads == null) break; from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, m_ListPage, m_List, null, new ArrayList(list))); break; } #region case 30: 3 minute game time account check case 30: // View all accounts less than 3 minutes of total online time. { //Change the "3" in the following line, to adjust deletion time. TimeSpan unusedGracePeriod = TimeSpan.FromMinutes(3); ArrayList results = new ArrayList(); foreach (Account acct in Accounts.GetAccounts()) { TimeSpan time = acct.TotalGameTime; //TotalGameTime from Account file. if (time <= unusedGracePeriod) { Console.WriteLine("Remove: " + acct.Username + " TotalGameTime: " + time + " <= " + unusedGracePeriod + ":Grace Period"); results.Add(acct); } else { Console.WriteLine("Keep: " + acct.Username + " TotalGameTime: " + time + " <= " + unusedGracePeriod + ":Grace Period"); } } if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "One match found.", results[0])); else from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, results, (results.Count == 0 ? "Nothing matched your search terms." : null), new ArrayList())); break; } #endregion case 31: // View all inactive accounts { ArrayList results = new ArrayList(); foreach (Account acct in Accounts.GetAccounts()) { if (acct.Inactive) results.Add(acct); } if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "One match found.", results[0])); else from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, results, (results.Count == 0 ? "Nothing matched your search terms." : null), new ArrayList())); break; } case 32: // View all banned accounts { ArrayList results = new ArrayList(); foreach (Account acct in Accounts.GetAccounts()) { if (acct.Banned) results.Add(acct); } if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "One match found.", results[0])); else from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, results, (results.Count == 0 ? "Nothing matched your search terms." : null), new ArrayList())); break; } #region original case 30 case 33: // View all empty accounts { ArrayList results = new ArrayList(); foreach (Account acct in Accounts.GetAccounts()) { bool empty = true; for (int i = 0; empty && i < acct.Length; ++i) empty = (acct[i] == null); if (empty) results.Add(acct); } if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, "One match found.", results[0])); else from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, results, (results.Count == 0 ? "Nothing matched your search terms." : null), new ArrayList())); break; } #endregion case 34: { goto case 20; } case 35: // Unmark house owners { ArrayList list = m_List; ArrayList rads = m_State as ArrayList; if (list == null || rads == null) break; ArrayList newRads = new ArrayList(); foreach (Account acct in rads) { bool hasHouse = false; for (int i = 0; i < acct.Length && !hasHouse; ++i) if (acct[i] != null && BaseHouse.HasHouse(acct[i])) hasHouse = true; if (!hasHouse) newRads.Add(acct); } from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, m_ListPage, m_List, null, newRads)); break; } case 36: // Clear login addresses { Account a = m_State as Account; if (a == null) break; IPAddress[] ips = a.LoginIPs; if (ips.Length == 0) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "This account has not yet been accessed.", m_State)); else from.SendGump(new WarningGump(1060635, 30720, string.Format("You are about to clear the address list for account {0} containing {1} {2}. Do you wish to continue?", a, ips.Length, (ips.Length == 1) ? "entry" : "entries"), 0xFFC000, 420, 280, RemoveLoginIPs_Callback, a)); break; } default: { index -= 50; Account a = m_State as Account; if (a != null && index >= 0 && index < a.Length) { Mobile m = a[index]; if (m != null) from.SendGump(new AdminGump(from, AdminGumpPage.ClientInfo, 0, null, null, m)); } else { index -= 6; if (m_List != null && index >= 0 && index < m_List.Count) { if (m_List[index] is Account) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, null, m_List[index])); else if (m_List[index] is DictionaryEntry) from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, (ArrayList)(((DictionaryEntry)m_List[index]).Value), null, new ArrayList())); } } break; } } break; } case 6: { switch (index) { case 0: { TextRelay matchEntry = info.GetTextEntry(0); string match = (matchEntry == null ? null : matchEntry.Text.Trim()); string notice = null; ArrayList results = new ArrayList(); if (string.IsNullOrEmpty(match)) { notice = "You must enter a username to search."; } else { for (int i = 0; i < Firewall.List.Count; ++i) { string check = Firewall.List[i].ToString(); if (check.IndexOf(match) >= 0) results.Add(Firewall.List[i]); } } if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.FirewallInfo, 0, null, "One match found.", results[0])); else if (results.Count > 1) from.SendGump(new AdminGump(from, AdminGumpPage.Firewall, 0, results, string.Format("Search results for : {0}", match), m_State)); else from.SendGump(new AdminGump(from, m_PageType, m_ListPage, m_List, notice == null ? "Nothing matched your search terms." : notice, m_State)); break; } case 1: { TextRelay relay = info.GetTextEntry(0); string text = (relay == null ? null : relay.Text.Trim()); if (string.IsNullOrEmpty(text)) { from.SendGump(new AdminGump(from, m_PageType, m_ListPage, m_List, "You must enter an address or pattern to add.", m_State)); } else if (!Utility.IsValidIP(text)) { from.SendGump(new AdminGump(from, m_PageType, m_ListPage, m_List, "That is not a valid address or pattern.", m_State)); } else { object toAdd = Firewall.ToFirewallEntry(text); CommandLogging.WriteLine(from, "{0} {1} firewalling {2}", from.AccessLevel, CommandLogging.Format(from), toAdd); Firewall.Add(toAdd); from.SendGump(new AdminGump(from, AdminGumpPage.FirewallInfo, 0, null, string.Format("{0} : Added to firewall.", toAdd), toAdd)); } break; } case 2: { InvokeCommand("Firewall"); from.SendGump(new AdminGump(from, m_PageType, m_ListPage, m_List, "Target the player to firewall.", m_State)); break; } case 3: { if (m_State is Firewall.IFirewallEntry) { CommandLogging.WriteLine(from, "{0} {1} removing {2} from firewall list", from.AccessLevel, CommandLogging.Format(from), m_State); Firewall.Remove(m_State); from.SendGump(new AdminGump(from, AdminGumpPage.Firewall, 0, null, string.Format("{0} : Removed from firewall.", m_State), null)); } break; } default: { index -= 4; if (m_List != null && index < m_List.Count) from.SendGump(new AdminGump(from, AdminGumpPage.FirewallInfo, 0, null, null, m_List[index])); break; } } break; } case 7: { Mobile m = m_State as Mobile; if (m == null) break; string notice = null; bool sendGump = true; switch (index) { case 0: { Map map = m.Map; Point3D loc = m.Location; if (map == null || map == Map.Internal) { map = m.LogoutMap; loc = m.LogoutLocation; } if (map != null && map != Map.Internal) { from.MoveToWorld(loc, map); notice = "You have been teleported to their location."; } break; } case 1: { m.MoveToWorld(from.Location, from.Map); notice = "They have been teleported to your location."; break; } case 2: { NetState ns = m.NetState; if (ns != null) { CommandLogging.WriteLine(from, "{0} {1} {2} {3}", from.AccessLevel, CommandLogging.Format(from), "kicking", CommandLogging.Format(m)); ns.Dispose(); notice = "They have been kicked."; } else { notice = "They are already disconnected."; } break; } case 3: { Account a = m.Account as Account; if (a != null) { CommandLogging.WriteLine(from, "{0} {1} {2} {3}", from.AccessLevel, CommandLogging.Format(from), "banning", CommandLogging.Format(m)); a.Banned = true; NetState ns = m.NetState; if (ns != null) ns.Dispose(); notice = "They have been banned."; } break; } case 6: { Properties.SetValue(from, m, "Blessed", "False"); notice = "They are now mortal."; break; } case 7: { Properties.SetValue(from, m, "Blessed", "True"); notice = "They are now immortal."; break; } case 8: { Properties.SetValue(from, m, "Squelched", "True"); notice = "They are now squelched."; break; } case 9: { Properties.SetValue(from, m, "Squelched", "False"); notice = "They are now unsquelched."; break; } case 10: { Properties.SetValue(from, m, "Hidden", "True"); notice = "They are now hidden."; break; } case 11: { Properties.SetValue(from, m, "Hidden", "False"); notice = "They are now unhidden."; break; } case 12: { CommandLogging.WriteLine(from, "{0} {1} killing {2}", from.AccessLevel, CommandLogging.Format(from), CommandLogging.Format(m)); m.Kill(); notice = "They have been killed."; break; } case 13: { CommandLogging.WriteLine(from, "{0} {1} resurrecting {2}", from.AccessLevel, CommandLogging.Format(from), CommandLogging.Format(m)); m.Resurrect(); notice = "They have been resurrected."; break; } case 14: { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, null, m.Account)); sendGump = false; break; } } if (sendGump) from.SendGump(new AdminGump(from, AdminGumpPage.ClientInfo, 0, null, notice, m_State)); switch (index) { case 3: { Account a = m.Account as Account; if (a != null) from.SendGump(new BanDurationGump(a)); break; } case 4: { from.SendGump(new PropertiesGump(from, m)); break; } case 5: { from.SendGump(new SkillsGump(from, m)); break; } } break; } case 8: { if (m_List != null && index < m_List.Count) { Account a = m_State as Account; if (a == null) break; if (m_PageType == AdminGumpPage.AccountDetails_Access_ClientIPs) { from.SendGump(new WarningGump(1060635, 30720, string.Format("You are about to firewall {0}. All connection attempts from a matching IP will be refused. Are you sure?", m_List[index]), 0xFFC000, 420, 280, Firewall_Callback, new object[] { a, m_List[index] })); } else if (m_PageType == AdminGumpPage.AccountDetails_Access_Restrictions) { ArrayList list = new ArrayList(a.IPRestrictions); list.Remove(m_List[index]); a.IPRestrictions = (string[])list.ToArray(typeof(string)); from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_Restrictions, 0, null, string.Format("{0} : Removed from list.", m_List[index]), a)); } } break; } case 9: { if (m_List != null && index < m_List.Count) { if (m_PageType == AdminGumpPage.AccountDetails_Access_ClientIPs) { object obj = m_List[index]; if (!(obj is IPAddress)) break; Account a = m_State as Account; if (a == null) break; ArrayList list = GetSharedAccounts((IPAddress)obj); if (list.Count > 1 || (list.Count == 1 && !list.Contains(a))) from.SendGump(new AdminGump(from, AdminGumpPage.Accounts, 0, list, null, new ArrayList())); else from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "There are no other accounts which share that address.", m_State)); } } break; } case 10: { if (m_List != null && index < m_List.Count) { if (m_PageType == AdminGumpPage.AccountDetails_Access_ClientIPs) { IPAddress ip = m_List[index] as IPAddress; if (ip == null) break; Account a = m_State as Account; if (a == null) break; from.SendGump(new WarningGump(1060635, 30720, string.Format("You are about to remove address {0} from account {1}. Do you wish to continue?", ip, a), 0xFFC000, 420, 280, RemoveLoginIP_Callback, new object[] { a, ip })); } } break; } } } private void Shutdown(bool restart, bool save) { CommandLogging.WriteLine(m_From, "{0} {1} shutting down server (Restart: {2}) (Save: {3})", m_From.AccessLevel, CommandLogging.Format(m_From), restart, save); if (save) InvokeCommand("Save"); Core.Kill(restart); } private void InvokeCommand(string c) { CommandSystem.Handle(m_From, string.Format("{0}{1}", CommandSystem.Prefix, c)); } public static void GetAccountInfo(Account a, out AccessLevel accessLevel, out bool online) { accessLevel = a.AccessLevel; online = false; for (int j = 0; j < a.Length; ++j) { Mobile check = a[j]; if (check == null) continue; if (check.AccessLevel > accessLevel) accessLevel = check.AccessLevel; if (check.NetState != null) online = true; } } private class AddCommentPrompt : Prompt { private readonly Account m_Account; public AddCommentPrompt(Account acct) { m_Account = acct; } public override void OnCancel(Mobile from) { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Comments, 0, null, "Request to add comment was canceled.", m_Account)); } public override void OnResponse(Mobile from, string text) { if (m_Account != null) { m_Account.Comments.Add(new AccountComment(from.RawName, text)); from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Comments, 0, null, "Comment added.", m_Account)); } } } private class AddTagNamePrompt : Prompt { private readonly Account m_Account; public AddTagNamePrompt(Account acct) { m_Account = acct; } public override void OnCancel(Mobile from) { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Tags, 0, null, "Request to add tag was canceled.", m_Account)); } public override void OnResponse(Mobile from, string text) { from.Prompt = new AddTagValuePrompt(m_Account, text); from.SendMessage("Enter the new tag value."); } } private class AddTagValuePrompt : Prompt { private readonly Account m_Account; private readonly string m_Name; public AddTagValuePrompt(Account acct, string name) { m_Account = acct; m_Name = name; } public override void OnCancel(Mobile from) { from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Tags, 0, null, "Request to add tag was canceled.", m_Account)); } public override void OnResponse(Mobile from, string text) { if (m_Account != null) { m_Account.AddTag(m_Name, text); from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Tags, 0, null, "Tag added.", m_Account)); } } } private class NetStateComparer : IComparer { public static readonly IComparer Instance = new NetStateComparer(); public int Compare(object x, object y) { if (x == null && y == null) return 0; else if (x == null) return -1; else if (y == null) return 1; NetState a = x as NetState; NetState b = y as NetState; if (a == null || b == null) throw new ArgumentException(); Mobile aMob = a.Mobile; Mobile bMob = b.Mobile; if (aMob == null && bMob == null) return 0; else if (aMob == null) return 1; else if (bMob == null) return -1; if (aMob.AccessLevel > bMob.AccessLevel) return -1; else if (aMob.AccessLevel < bMob.AccessLevel) return 1; else return Insensitive.Compare(aMob.Name, bMob.Name); } } private class AccountComparer : IComparer { public static readonly IComparer Instance = new AccountComparer(); public int Compare(object x, object y) { if (x == null && y == null) return 0; else if (x == null) return -1; else if (y == null) return 1; Account a = x as Account; Account b = y as Account; if (a == null || b == null) throw new ArgumentException(); AccessLevel aLevel, bLevel; bool aOnline, bOnline; GetAccountInfo(a, out aLevel, out aOnline); GetAccountInfo(b, out bLevel, out bOnline); if (aOnline && !bOnline) return -1; else if (bOnline && !aOnline) return 1; else if (aLevel > bLevel) return -1; else if (aLevel < bLevel) return 1; else return Insensitive.Compare(a.Username, b.Username); } } } }