public static void CrashBug(CharData ch, string[] str) { if( ch == null ) return; if (str.Length == 0) { ch.SendText("Report what crash bug?\r\n"); return; } string text = String.Join(" ", str); Issue issue = new Issue(); issue.IssueDetail = new IssueEntry(ch.Name, text); issue.OpenedByImmortal = ch.IsImmortal(); issue.IssueType = Issue.Type.bug; issue.IssuePriority = Issue.Priority.highest; if (ch.InRoom != null) { issue.RoomIndexNumber = ch.InRoom.IndexNumber; } Database.IssueList.Add(issue); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_DEBUG, 0, String.Format("New CRASH BUG, issue # {0} created by {1}. Text is:\n{2}", issue.IssueNumber, ch.Name, text)); Issue.Save(); ch.SendText("Crash bug report recorded. Thank you.\r\n"); return; }
/// <summary> /// Report a typo, which is logged by the issue system. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Typo(CharData ch, string[] str) { if( ch == null ) return; if (str.Length == 0) { ch.SendText("There was a Typo in your Typo report.\r\n"); return; } string text = String.Join(" ", str); Issue issue = new Issue(); issue.IssueDetail = new IssueEntry(ch.Name, text); issue.OpenedByImmortal = ch.IsImmortal(); issue.IssueType = Issue.Type.typo; issue.IssuePriority = Issue.Priority.low; if (ch.InRoom != null) { issue.RoomIndexNumber = ch.InRoom.IndexNumber; } Database.IssueList.Add(issue); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_DEBUG, 0, String.Format("New Typo, issue # {0} created by {1}. Text is:\n{2}", issue.IssueNumber, ch.Name, text)); Issue.Save(); ch.SendText("Yore typo report haz been rekorded. Thank yew.\r\n"); return; }
public static void RequestHelp(CharData ch, string[] str) { if( ch == null ) return; if (str.Length == 0) { ch.SendText("What would you like to request a help entry for?\r\n"); return; } string text = String.Join(" ", str); Issue issue = new Issue(); issue.IssueDetail = new IssueEntry(ch.Name, "Help Request: " + text); issue.OpenedByImmortal = ch.IsImmortal(); issue.IssueType = Issue.Type.helpentryrequest; issue.IssuePriority = Issue.Priority.lowest; if (ch.InRoom != null) { issue.RoomIndexNumber = ch.InRoom.IndexNumber; } Database.IssueList.Add(issue); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_DEBUG, 0, String.Format("New help entry request, issue # {0} created by {1}. Text is:\n{2}", issue.IssueNumber, ch.Name, text)); Issue.Save(); ch.SendText("Help entry request recorded. Thank you.\r\n"); return; }
/// <summary> /// Command to view and manipulate entries in the issue system. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void IssueCommand(CharData ch, string[] str) { if( ch == null ) return; if (!ch.IsImmortal()) { ch.SendText("Yes, you do have issues.\r\n"); return; } if ((str.Length == 0) || "list".StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase)) { ch.SendText(Issue.ShowIssues()); return; } if ("show".StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase)) { if (str.Length < 2) { ch.SendText("Show which issue number?\r\n"); return; } int val; bool ok = Int32.TryParse(str[1], out val); if (ok) { ch.SendText(Issue.Format(val)); return; } ch.SendText("That's not a valid issue number.\r\n"); return; } if ("add".StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase) || "create".StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase)) { String text = String.Join(" ", str, 1, (str.Length - 1)); Issue issue = new Issue(); issue.IssueDetail = new IssueEntry(ch.Name, text); issue.OpenedByImmortal = ch.IsImmortal(); issue.IssueType = Issue.Type.bug; issue.IssuePriority = Issue.Priority.medium; if (ch.InRoom != null) { issue.RoomIndexNumber = ch.InRoom.IndexNumber; } Database.IssueList.Add(issue); string output = String.Format("New issue # {0}: {1} (created by {2}).\n", issue.IssueNumber, text, ch.Name); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_DEBUG, 0, output); Issue.Save(); ch.SendText(output); return; } if ("close".StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase)) { if (str.Length < 2) { ch.SendText("Close which issue number?\r\n"); return; } if (str.Length < 3) { ch.SendText("Syntax: issue close <number> <resolution text>\r\n"); return; } int val; bool ok = Int32.TryParse(str[1], out val); if (ok) { foreach (Issue iss in Database.IssueList) { if (iss.IssueNumber == val) { iss.Closed = true; iss.Closure = new IssueEntry(); iss.Closure.Name = ch.Name; string text = String.Empty; for (int i = 2; i < str.Length; i++) { text += str[i] + " "; } iss.Closure.Text = text; iss.Closure.UpdateTime = DateTime.Now; Issue.Save(); ch.SendText("Issue " + val + " closed with resolution " + text + "\r\n"); return; } } } ch.SendText("That's not a valid issue number.\r\n"); } else if ("update".StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase)) { if (str.Length < 2) { ch.SendText("Update which issue number?\r\n"); return; } if (str.Length < 3) { ch.SendText("Syntax: issue update <number> <text>\r\n"); return; } int val; bool ok = Int32.TryParse(str[1], out val); if (ok) { foreach (Issue iss in Database.IssueList) { if (iss.IssueNumber == val) { IssueEntry ie = new IssueEntry(); ie.Name = ch.Name; string text = String.Empty; for( int i = 2; i < str.Length; i++ ) { text += str[i] + " "; } ie.Text = text; ie.UpdateTime = DateTime.Now; iss.Updates.Add(ie); Issue.Save(); ch.SendText("Issue " + val + " updated with text " + text + "\r\n"); return; } } } } else if ("priority".StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase)) { if (str.Length < 2) { ch.SendText("Set priority on which issue number?\r\n"); return; } if (str.Length < 3) { ch.SendText("Syntax: issue priority <number> <lowest|low|medium|high|highest>\r\n"); return; } int val; bool ok = Int32.TryParse(str[1], out val); if (ok) { foreach (Issue iss in Database.IssueList) { if (iss.IssueNumber == val) { try { iss.IssuePriority = (Issue.Priority)Enum.Parse(typeof(Issue.Priority), str[2], true); Issue.Save(); ch.SendText("Issue " + val + " priority set to " + iss.IssuePriority + ".\r\n"); } catch (Exception) { ch.SendText("That's not a valid priority value. Valid values are lowest, low, medium, high, and highest."); return; } return; } } } ch.SendText("That's not a valid issue number.\r\n"); } else { ch.SendText(Issue.ShowIssues()); } return; }
/// <summary> /// Command to suggest an idea. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Idea(CharData ch, string[] str) { if( ch == null ) return; if (str.Length == 0) { ch.SendText("What idea? The Implementors look at you quizzically.\r\n"); return; } string text = String.Join(" ", str); Issue issue = new Issue(); issue.IssueDetail = new IssueEntry(ch.Name, text); issue.OpenedByImmortal = ch.IsImmortal(); issue.IssueType = Issue.Type.idea; issue.IssuePriority = Issue.Priority.lowest; if (ch.InRoom != null) { issue.RoomIndexNumber = ch.InRoom.IndexNumber; } Database.IssueList.Add(issue); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_DEBUG, 0, String.Format("New idea, issue # {0} created by {1}. Text is:\n{2}", issue.IssueNumber, ch.Name, text)); Issue.Save(); ch.SendText("Idea recorded. Thank you.\r\n"); return; }
/// <summary> /// Loads the entire MUD database including all classes, races, areas, helps, sytem data, etc. /// </summary> public void LoadDatabase() { DatabaseIsBooting = true; Log.Trace(DateTime.Now.ToShortDateString() + " BOOT: -------------------------[ Boot Log ]-------------------------"); Log.Trace("Validating that player directories exist."); for (Char letter = 'a'; letter <= 'z'; letter++) { String directory = FileLocation.PlayerDirectory + letter; if (!Directory.Exists(directory)) { Log.Trace("Creating directory: " + directory + "."); Directory.CreateDirectory(directory); } } Log.Trace("Player directories validated."); Log.Trace("Loading Database.SystemData."); Sysdata.Load(); SystemData.CurrentTime = DateTime.Now; SystemData.GameBootTime = SystemData.CurrentTime; // Set time and weather. Log.Trace("Setting time and weather."); SystemData.SetWeather(); Log.Trace("Loading static rooms."); StaticRooms.Load(); Log.Trace("Loaded " + StaticRooms.Count + " static rooms."); Log.Trace("Loading spells."); Spell.LoadSpells(); Log.Trace("Loaded " + Spell.SpellList.Count + " spells."); Log.Trace("Loading skills."); Skill.LoadSkills(); Log.Trace("Loaded " + Skill.SkillList.Count + " skills."); Log.Trace("Loading races."); Race.LoadRaces(); Log.Trace("Loaded " + Race.Count + " races."); Log.Trace("Initializing skill Levels."); { int cclass; foreach (KeyValuePair <String, Skill> kvp in Skill.SkillList) { for (cclass = 0; cclass < CharClass.ClassList.Length; cclass++) { kvp.Value.ClassAvailability[cclass] = Limits.LEVEL_LESSER_GOD; } } foreach (KeyValuePair <String, Spell> kvp in Spell.SpellList) { for (cclass = 0; cclass < CharClass.ClassList.Length; cclass++) { kvp.Value.SpellCircle[cclass] = Limits.MAX_CIRCLE + 3; } } } Log.Trace("Loading classes."); CharClass.LoadClasses(true); Log.Trace("Loaded " + CharClass.Count + " classes."); Log.Trace("Assigning spell circles."); AssignSpellCircles(); Log.Trace("Assigned spell circles."); Log.Trace("Loading socials."); SocialList = Socials.Load(); Log.Trace("Loaded " + Social.Count + " socials."); Log.Trace("Loading bans."); LoadBans(); Log.Trace("Loaded " + BanList.Count + " bans."); Log.Trace("Loading help entries."); HelpList = Help.Load(FileLocation.SystemDirectory + FileLocation.HelpFile); Log.Trace("Loaded " + Help.Count + " help entries."); Log.Trace("Loading screens."); Screen.Load(FileLocation.SystemDirectory + FileLocation.ScreenFile, FileLocation.BlankSystemFileDirectory + FileLocation.ScreenFile); Log.Trace("Loaded " + Screen.Count + " screens."); // Chatbots have to be loaded before mobs. Log.Trace("Loading chatbots."); ChatterBot.Load(); Log.Trace("Loaded " + ChatterBot.Count + " chatbots."); // Read in all the area files. Log.Trace("Reading in area files..."); LoadAreaFiles(); Log.Trace("Loaded " + Area.Count + " areas."); string buf = String.Format("Loaded {0} mobs, {1} objects, {2} rooms, {3} shops, {4} helps, {5} resets, and {6} quests.", MobTemplate.Count, ObjTemplate.Count, Room.Count, Shop.Count, Help.Count, Reset.Count, QuestData.Count); Log.Trace(buf); Log.Trace("Loading guilds."); Guild.LoadGuilds(); Log.Trace("Loaded " + Guild.Count + " guilds."); Log.Trace("Loading corpses."); CorpseList = CorpseData.Load(); Log.Trace("Loaded " + CorpseData.Count + " corpses."); Log.Trace("Loading crimes."); Crime.Load(); Log.Trace("Loaded " + Crime.Count + " crimes."); Log.Trace("Loading fraglist."); FraglistData.Fraglist.Load(); Log.Trace("Loading issues."); Issue.Load(); Log.Trace("Loaded " + Issue.Count + " issues."); Log.Trace("Loading bounties."); Bounty.Load(); Log.Trace("Loaded " + Bounty.Count + " bounties."); Log.Trace("Initializing movement parameters."); Movement.Initialize(); Log.Trace("Movement parameters initialized."); // Only compile spells that have attached code. Otherwise use default handlers. Log.Trace("Compiling spells."); int good = 0; int bad = 0; foreach (KeyValuePair <String, Spell> kvp in Spell.SpellList) { if (!String.IsNullOrEmpty(kvp.Value.Code)) { if (!SpellFunction.CompileSpell(kvp.Value)) { ++bad; } else { ++good; } } } Log.Trace("Done compiling spells. " + good + " were successful, " + bad + " failed."); // Links up exits and makes rooms runtime-ready so we can access them. Log.Trace("Linking exits."); LinkExits(); // This has to be after LinkExits(). Log.Trace("Loading zone connections."); ZoneConnectionList = ZoneConnection.Load(); // Link zones together based on file. foreach (ZoneConnection connection in ZoneConnectionList) { RoomTemplate room1 = Room.GetRoom(connection.FirstRoomNumber); RoomTemplate room2 = Room.GetRoom(connection.SecondRoomNumber); Exit.Direction direction = connection.FirstToSecondDirection; if (room1 != null && room2 != null && direction != Exit.Direction.invalid) { Exit exit = new Exit(); exit.TargetRoom = room2; exit.IndexNumber = connection.SecondRoomNumber; room1.ExitData[(int)direction] = exit; exit = new Exit(); exit.TargetRoom = room1; exit.IndexNumber = connection.FirstRoomNumber; room2.ExitData[(int)Exit.ReverseDirection(direction)] = exit; Log.Trace("Connected " + room1.Area.Name + " to " + room2.Area.Name + " at " + room1.IndexNumber); } else { Log.Error("Unable to connect room " + connection.FirstRoomNumber + " to " + connection.SecondRoomNumber + " in direction " + connection.FirstToSecondDirection); } } Log.Trace("Loaded " + ZoneConnectionList.Count + " zone connections."); DatabaseIsBooting = false; Log.Trace("Resetting areas."); AreaUpdate(); Log.Trace("Creating events."); Event.CreateEvent(Event.EventType.save_corpses, Event.TICK_SAVE_CORPSES, null, null, null); Event.CreateEvent(Event.EventType.save_sysdata, Event.TICK_SAVE_SYSDATA, null, null, null); Event.CreateEvent(Event.EventType.violence_update, Event.TICK_COMBAT_UPDATE, null, null, null); Event.CreateEvent(Event.EventType.area_update, Event.TICK_AREA, null, null, null); Event.CreateEvent(Event.EventType.room_update, Event.TICK_ROOM, null, null, null); Event.CreateEvent(Event.EventType.object_special, Event.TICK_OBJECT, null, null, null); Event.CreateEvent(Event.EventType.mobile_update, Event.TICK_MOBILE, null, null, null); Event.CreateEvent(Event.EventType.weather_update, Event.TICK_WEATHER, null, null, null); Event.CreateEvent(Event.EventType.char_update, Event.TICK_CHAR_UPDATE, null, null, null); Event.CreateEvent(Event.EventType.object_update, Event.TICK_OBJ_UPDATE, null, null, null); Event.CreateEvent(Event.EventType.aggression_update, Event.TICK_AGGRESS, null, null, null); Event.CreateEvent(Event.EventType.memorize_update, Event.TICK_MEMORIZE, null, null, null); Event.CreateEvent(Event.EventType.hit_gain, Event.TICK_HITGAIN, null, null, null); Event.CreateEvent(Event.EventType.mana_gain, Event.TICK_MANAGAIN, null, null, null); Event.CreateEvent(Event.EventType.move_gain, Event.TICK_MOVEGAIN, null, null, null); Event.CreateEvent(Event.EventType.heartbeat, Event.TICK_WEATHER, null, null, null); return; }