static void Main(string[] args) { // Get the port number. ushort port = 4502; if ( args != null ) { foreach( string arg in args ) { bool success = ushort.TryParse( arg, out port ); if( success ) break; } } // Set up logging. Log.ExceptionDetailsEnabled = true; Log.TraceEnabled = true; // Create the socket engine. SocketConnection listenSocket = new SocketConnection(); // Display our version information. string assemblyName = listenSocket.GetType().Assembly.GetName().Name; string assemblyVersion = listenSocket.GetType().Assembly.GetName().Version.ToString(); System.IO.FileInfo assemblyInfo = new System.IO.FileInfo( listenSocket.GetType().Assembly.Location ); DateTime assemblyDate = assemblyInfo.LastWriteTime; Log.Trace( "Running " + assemblyName + " version " + assemblyVersion + " located at " + assemblyInfo + " and created on " + assemblyDate.ToShortDateString() + "."); // Initialize sockets, load the database, and run the game. System.Net.Sockets.Socket control = listenSocket.InitializeSocket( port ); Database database = new Database(); database.LoadDatabase( ); Log.Trace(String.Format("{0} MUD is now running on port {1}.", Database.SystemData.MudName, port)); try { listenSocket.MainGameLoop(control); } catch (Exception ex) { Log.Error("Unhandled exception running main game loop: " + ex.ToString()); control.Close(); return; } control.Close(); // End of game. Log.Trace( "Normal shutdown of game." ); return; }
public static void Finger(CharData ch, string[] str) { if( ch == null ) return; CharData victim; SocketConnection victDD; bool loggedIn; if (ch.IsNPC()) return; if (str.Length == 0) { ch.SendText("Finger whom?\r\n"); return; } /* Look for the character logged in. */ if ((victim = ch.GetCharWorld(str[0]))) { if (victim.IsNPC()) { ch.SendText("Don't finger mobs.\r\n"); return; } if (!victim.Socket) { ch.SendText("Character is linkdead.\r\n"); if (!CharData.LoadPlayer((victDD = new SocketConnection()), str[0])) { /* If not in save files, they don't exist. */ ch.SendText("This character does not exist.\r\n"); return; } loggedIn = false; } else { loggedIn = true; ch.SendText("This character is logged in.\r\n"); victDD = victim.Socket; } } /* If not, then load from save files. */ else { loggedIn = false; if (!(CharData.LoadPlayer((victDD = new SocketConnection()), str[0].ToUpper()))) { /* If not in save files, they don't exist. */ ch.SendText("This character does not exist.\r\n"); return; } else ch.SendText("This character is not logged in.\r\n"); victim = victDD.Original ? victDD.Original : victDD.Character; } /* Display general character info. */ string buf = String.Format("Name: {0}. Title: {1}&n.\r\n", victDD.Original ? victDD.Original.Name : victDD.Character ? victDD.Character.Name : "(none)", (!victim.IsNPC() && ((PC)victim).Title.Length != 0) ? ((PC)victim).Title : "(none)"); ch.SendText(buf); buf = String.Format("Guild: {0}&n. Level: {1}&n.\r\n", (!victim.IsNPC() && ((PC)victim).GuildMembership != null) ? ((PC)victim).GuildMembership.Name : "(none)", victim.Level); ch.SendText(buf); buf = String.Format("Class: {0}&n. Room: {1}&n. Race: {2}&n.\r\n", (victim.CharacterClass != null ? victim.CharacterClass.WholistName : "(Undefined)"), victim.InRoom ? victim.InRoom.IndexNumber : -1, (victim.GetRace() < Race.RaceList.Length && victim.GetRace() >= 0) ? Race.RaceList[victim.GetRace()].ColorName : "(Undefined)"); ch.SendText(buf); /* Messages specific to whether a player is logged in. */ if (loggedIn) { if (victim.InRoom) { buf = String.Format("In room: {0}&n ({1}).\r\n", victim.InRoom.Title.Length != 0 ? victim.InRoom.Title : "(none)", victim.InRoom.IndexNumber); ch.SendText(buf); } buf = String.Format("On since: {0}", victim.LogonTime); } else buf = String.Format("Created: {0} Birthdate: {1}", ((PC)victim).Created, ((PC)victim).Birthdate); ch.SendText(buf); if (loggedIn) { buf = String.Format("Last save: {0}", victim.SaveTime); ch.SendText(buf); } else { buf = String.Format("Last logged in: {0}", victim.SaveTime); ch.SendText(buf); } /* Close rented chars pfile (w/out saving!). */ if (!loggedIn) victDD = null; return; }
/// <summary> /// Demote: Decrease the rank of a guild member. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Demote(CharData ch, string[] str) { if( ch == null ) return; SocketConnection victimSocket; int count; bool loggedIn = false; if (str.Length == 0) { ch.SendText("Demote whom?\r\n"); return; } if (!ch.IsGuild() || ((PC)ch).GuildRank != Guild.Rank.leader) { ch.SendText("You don't have the power to do this.\r\n"); return; } Guild guild = ((PC)ch).GuildMembership; CharData victim = null; foreach (CharData worldChar in Database.CharList) { if (worldChar.IsNPC()) { continue; } if (MUDString.NameContainedIn(str[0], worldChar.Name)) { victim = worldChar; loggedIn = true; break; } } if (victim == null) { if (!(CharData.LoadPlayer((victimSocket = new SocketConnection()), str[0]))) { ch.SendText("Who's that?!\r\n"); return; } victim = victimSocket.Original ? victimSocket.Original : victimSocket.Character; loggedIn = false; } if (victim.IsNPC()) { ch.SendText("NPCs are not guildable!\r\n"); return; } if (!ch.IsSameGuild(victim)) { SocketConnection.Act("$N&n isn't even from $t.", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character); return; } switch (((PC)victim).GuildRank) { default: ch.SendText("You can't demote this person.\r\n"); return; case Guild.Rank.normal: ch.SendText("You can't demote them any further.\r\n"); return; case Guild.Rank.senior: case Guild.Rank.officer: case Guild.Rank.deputy: break; case Guild.Rank.leader: if (str.Length > 1 && MUDString.StringsNotEqual(str[1], "confirm")) { ch.SendText("Try 'demote leadername confirm' to demote a leader.\r\n"); return; } break; } ((PC)victim).GuildRank--; Guild.Rank newrank = ((PC)victim).GuildRank; SetTitle(victim, guild.RankNames[(int)((PC)victim).GuildRank]); string text = String.Format("Log {0}: demoting {1} to {2}", ch.Name, victim.Name, ((PC)ch).GuildMembership.Name); Database.LogGuild(text); text = String.Format( "The grand Overlord {0} says:\r\n\r\n" + "'I hereby demote you {1} to {2}!!!'\r\n" + "You should make more efforts to improve!", ch.Name, victim.Name, newrank); if (loggedIn) { victim.SendText(text); } SocketConnection.Act("You have demoted $N to $t.", ch, newrank.ToString(), victim, SocketConnection.MessageTarget.character); for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count) { if (!MUDString.StringsNotEqual(guild.Members[count].Name, victim.Name)) { guild.Members[count].Rank = ((PC)victim).GuildRank; } } CharData.SavePlayer(victim); guild.Save(); /* Close rented chars pfile. */ if (!loggedIn) { victimSocket = null; } return; }
/// <summary> /// Promote target to another rank in the guild. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Promote(CharData ch, string[] str) { if( ch == null ) return; SocketConnection victimSocket; int count; bool loggedIn = false; if (ch.IsNPC()) { return; } if (str.Length == 0) { ch.SendText("Promote whom?\r\n"); return; } if (!ch.IsGuild() || ((PC)ch).GuildRank != Guild.Rank.leader) { ch.SendText("You don't have the power to do this. Only a leader may promote someone.\r\n"); return; } Guild guild = ((PC)ch).GuildMembership; CharData victim = null; foreach (CharData worldChar in Database.CharList) { if (worldChar.IsNPC()) { continue; } if (MUDString.NameContainedIn(str[0], worldChar.Name)) { victim = worldChar; loggedIn = true; break; } } if (victim == null) { if (!(CharData.LoadPlayer((victimSocket = new SocketConnection()), str[0]))) { ch.SendText("Who's that?!\r\n"); return; } victim = victimSocket.Original ? victimSocket.Original : victimSocket.Character; loggedIn = false; } if (victim.IsNPC() || victim == ch) { return; } if (!ch.IsSameGuild(victim)) { SocketConnection.Act("$N&n isn't even from $t.", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character); return; } // This is technically where we would give them their guild badges. switch (((PC)victim).GuildRank) { default: return; case Guild.Rank.normal: case Guild.Rank.officer: case Guild.Rank.senior: case Guild.Rank.deputy: break; case Guild.Rank.leader: ch.SendText("You may not promote that person any further.\r\n"); return; } ((PC)victim).GuildRank++; Guild.Rank newrank = ((PC)victim).GuildRank; SetTitle(victim, guild.RankNames[(int)((PC)victim).GuildRank]); string text = String.Format("Log {0}: promoting {1} to {2} in guild {3}", ch.Name, victim.Name, newrank, ((PC)ch).GuildMembership.Name); Database.LogGuild(text); text = String.Format( "The grand Overlord {0} says:\r\n\r\nI hereby promote you {1} to {2}!'\r\n", ch.Name, victim.Name, newrank); if (loggedIn) { victim.SendText(text); } SocketConnection.Act("You have promoted $N&n to $t.", ch, newrank.ToString(), victim, SocketConnection.MessageTarget.character); for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count) { if (!MUDString.StringsNotEqual(guild.Members[count].Name, victim.Name)) { guild.Members[count].Rank = ((PC)victim).GuildRank; } } CharData.SavePlayer(victim); guild.Save(); /* Close rented chars pfile. */ if (!loggedIn) { victimSocket = null; } return; }
/// <summary> /// Kick a character out of a guild. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void KickOut(CharData ch, string[] str) { if( ch == null ) return; SocketConnection victimSocket; bool loggedIn = false; if (str.Length == 0) { ch.SendText("Kick out whom?\r\n"); return; } if (!ch.IsGuild() || ((PC)ch).GuildRank < Guild.Rank.officer) { ch.SendText("You don't have the power to do this.\r\n"); return; } Guild guild = ((PC)ch).GuildMembership; CharData victim = null; foreach (CharData worldChar in Database.CharList) { if (worldChar.IsNPC()) { continue; } if (MUDString.NameContainedIn(str[0], worldChar.Name)) { victim = worldChar; loggedIn = true; break; } } if (victim == null) { if (!(CharData.LoadPlayer((victimSocket = new SocketConnection()), str[0]))) { ch.SendText("Who's that?!\r\n"); return; } victim = victimSocket.Original ? victimSocket.Original : victimSocket.Character; loggedIn = false; } if (victim.IsNPC()) { return; } if (victim == ch) { ch.SendText("Try &+rsociety secede&n!\r\n"); return; } if (!ch.IsSameGuild(victim)) { SocketConnection.Act("$N&n isn't even from $t.", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character); return; } if (((PC)ch).GuildRank <= ((PC)victim).GuildRank) { ch.SendText("You don't have the power to do this.\r\n"); return; } string text = String.Format("Log {0}: kicking {1} from {2}", ch.Name, victim.Name, ((PC)ch).GuildMembership.Name); Database.LogGuild(text); // this _function _resets member data victim.RemoveFromGuild(); ((PC)victim).GuildRank = Guild.Rank.normal; if (loggedIn) { victim.SendText("&+RYou have been booted from your guild!&n\r\n"); } ch.SendText("You have kicked them out of the guild.\r\n"); CharData.SavePlayer(victim); guild.Save(); /* Close rented chars pfile. */ if (!loggedIn) { victimSocket = null; } return; }
/// <summary> /// Accepts an incoming socket connection. /// </summary> /// <param name="control"></param> static void AcceptSocket(Socket control) { if (control == null) { Log.Error("SocketConnection.AcceptSocket() called with null control socket."); return; } string text = String.Empty; Socket socket; if( ( socket = control.Accept()) == null ) { throw new Exception( "Exception: " + "AcceptSocket: accept returned null" ); } SocketConnection newSocket = new SocketConnection(); newSocket._socket = socket; newSocket.Host = socket.RemoteEndPoint.ToString(); String logStr = String.Format( "New connection: {0} ({1})", newSocket.Host, text ); ImmortalChat.SendImmortalChat( null, ImmortalChat.IMMTALK_LOGINS, Limits.LEVEL_OVERLORD, logStr ); Log.Info(logStr); // Site ban list, for those bastards who just don't know how to behave. foreach( BanData ban in Database.BanList ) { if( !MUDString.IsSuffixOf( ban.Name, newSocket.Host ) ) { newSocket.WriteToSocket( "Your site has been banned from this Mud.\r\n",false); socket.Close(); return; } } // Add to our socket list. Database.SocketList.Add( newSocket ); // Hidden option #5 is "enhanced terminal". This is automatically sent by the wxMudClient and // WPFMUDClient. newSocket.WriteToBuffer( "Enter your terminal type (0 for ASCII, 1 for ANSI): " ); // Keep track of number of players and maximum number of players. if( ++Database.SystemData.NumPlayers > Database.SystemData.MaxPlayers ) Database.SystemData.MaxPlayers = Database.SystemData.NumPlayers; if( Database.SystemData.MaxPlayers > Database.SystemData.MaxPlayersEver ) { Database.SystemData.MaxPlayersTime = DateTime.Now; Database.SystemData.MaxPlayersEver = Database.SystemData.MaxPlayers; string logbuf = "Broke all-time maximum player record: " + Database.SystemData.MaxPlayersEver; Log.Trace( logbuf ); Sysdata.Save(); } return; }
/// <summary> /// Loads a player from disk. /// </summary> /// <param name="socket">The player's socket connection.</param> /// <param name="name">The character _name.</param> /// <returns>Boolean value representing success/failure.</returns> public static bool LoadPlayer(SocketConnection socket, string name) { name = name.ToUpper(); Log.Trace("Loading character: " + name + "."); string strsave = FileLocation.PlayerDirectory + MUDString.LowercaseInitial(name) + "/" + name + ".xml"; PC ch = PC.LoadFile(strsave); if (ch == null) { Log.Trace("CharData.LoadPlayer(): " + name + " not loaded."); return false; } if (socket) { socket.Character = ch; ch.Socket = socket; } ch.CastingTime = 0; ch.CastingSpell = 0; ch.CharacterClass = CharClass.ClassList[ch.CharClassNumber]; Log.Trace("CharData.LoadPlayer(): Successfully loaded " + name + "."); return true; }