diff --git a/Admin/IW4M ADMIN.csproj b/Admin/IW4M ADMIN.csproj index 71362e7a0..1c25279d7 100644 --- a/Admin/IW4M ADMIN.csproj +++ b/Admin/IW4M ADMIN.csproj @@ -107,7 +107,6 @@ - @@ -141,7 +140,7 @@ PreserveNewest - + PreserveNewest @@ -157,7 +156,7 @@ Always - Always + PreserveNewest Always diff --git a/Admin/Main.cs b/Admin/Main.cs index 3d38694d0..0a24a7505 100644 --- a/Admin/Main.cs +++ b/Admin/Main.cs @@ -44,6 +44,19 @@ namespace IW4MAdmin if (serverManager.getServers() != null) Program.getManager().mainLog.Write("IW4M Now Initialized!", Log.Level.Production); + String userInput; + Server serverToExecuteOn = serverManager.getServers()[0]; + Player Origin = new Player("IW4MAdmin Console", "", -1, Player.Permission.Console, -1, "", 0, ""); + + do + { + userInput = Console.ReadLine(); + Event E = new Event(Event.GType.Say, userInput, Origin, null, serverToExecuteOn); + Origin.lastEvent = E; + serverToExecuteOn.processEvent(E); + Console.Write('>'); + + } while (userInput != null && serverManager.isRunning()); serverMGRThread.Join(); serverManager.mainLog.Write("Shutting down IW4MAdmin...", Log.Level.Debug); diff --git a/Admin/Manager.cs b/Admin/Manager.cs index 289276849..a365753aa 100644 --- a/Admin/Manager.cs +++ b/Admin/Manager.cs @@ -60,16 +60,20 @@ namespace IW4MAdmin if (S == null) continue; - if (!isIW4MStillRunning(S.pID())) + if (!isIW4MStillRunning(S.pID()) || !S.isRunning) { Thread Defunct = ThreadList[S.pID()]; + + if (!S.isRunning) + Utilities.shutdownInterface(S.pID()); + S.isRunning = false; if (Defunct != null) { Defunct.Join(); ThreadList[S.pID()] = null; } - mainLog.Write("Server with PID #" + S.pID() + " no longer appears to be running.", Log.Level.Debug); + mainLog.Write("Server with PID #" + S.pID() + " can no longer be monitored.", Log.Level.Debug); activePIDs.Remove(S.pID()); defunctServers.Add(S); } @@ -98,6 +102,11 @@ namespace IW4MAdmin ThreadList[T.Key].Join(); } + public bool isRunning() + { + return activePIDs.Count != 0; + } + public List getServers() { return Servers; diff --git a/Admin/Plugins.cs b/Admin/Plugins.cs index 9b73557a7..43a7803b2 100644 --- a/Admin/Plugins.cs +++ b/Admin/Plugins.cs @@ -40,6 +40,7 @@ namespace IW4MAdmin assemblies.Add(assembly); } + int totalLoaded = 0; foreach (Assembly Plugin in assemblies) { if (Plugin != null) @@ -47,13 +48,14 @@ namespace IW4MAdmin Type[] types = Plugin.GetTypes(); foreach(Type assemblyType in types) { - if(assemblyType.IsClass && assemblyType.BaseType.Name == "Notify") + if(assemblyType.IsClass && assemblyType.BaseType.Name == "Plugin") { Object notifyObject = Activator.CreateInstance(assemblyType); Plugin newNotify = (Plugin)notifyObject; potentialNotifies.Add(newNotify); newNotify.onLoad(); - Program.getManager().mainLog.Write("Loaded event plugin \"" + assemblyType.Name + "\"", Log.Level.All); + Program.getManager().mainLog.Write("Loaded plugin \"" + newNotify.Name + "\"" + " [" + newNotify.Version + "]", Log.Level.Debug); + totalLoaded++; } else if (assemblyType.IsClass && assemblyType.BaseType.Name == "Command") @@ -61,14 +63,14 @@ namespace IW4MAdmin Object commandObject = Activator.CreateInstance(assemblyType); Command newCommand = (Command)commandObject; potentialCommands.Add(newCommand); - Program.getManager().mainLog.Write("Loaded command plugin \"" + newCommand.Name + "\"", Log.Level.All); + Program.getManager().mainLog.Write("Registered command \"" + newCommand.Name + "\"", Log.Level.Debug); + totalLoaded++; } - - else - Program.getManager().mainLog.Write("Ignoring invalid plugin \"" + assemblyType.Name + "\"", Log.Level.All); } } } + + Program.getManager().mainLog.Write("Loaded " + totalLoaded + " plugins.", Log.Level.Production); return true; } } diff --git a/Admin/Server.cs b/Admin/Server.cs index 7b35cb76a..bcf9424d0 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -14,7 +14,6 @@ namespace IW4MAdmin { public IW4MServer(string address, int port, string password, int H, int PID) : base(address, port, password, H, PID) { - playerHistory = new Queue(); commandQueue = new Queue(); } @@ -429,8 +428,22 @@ namespace IW4MAdmin { Event curEvent = events.Peek(); processEvent(curEvent); - foreach (Notify E in PluginImporter.potentialNotifies) - E.onEvent(curEvent); + foreach (Plugin P in PluginImporter.potentialNotifies) + { + try + { + P.onEvent(curEvent); + } + + catch (Exception Except) + { + Log.Write(String.Format("The plugin \"{0}\" (v{1}) generated an error. ( see log )", P.Name, P.Version), Log.Level.Production); + Log.Write(String.Format("Error Message: {0}", Except.Message), Log.Level.Debug); + Log.Write(String.Format("Error Trace: {0}", Except.StackTrace), Log.Level.Debug); + continue; + } + + } events.Dequeue(); } if (commandQueue.Count > 0) @@ -465,6 +478,7 @@ namespace IW4MAdmin #if DEBUG == false Broadcast("IW4M Admin is now ^2ONLINE"); + int numExceptions = 0; #endif while (isRunning) @@ -480,7 +494,7 @@ namespace IW4MAdmin { while (playerHistory.Count > 144 ) // 12 times a minute for 12 hours playerHistory.Dequeue(); - playerHistory.Enqueue(new pHistory(lastCount, clientnum)); + playerHistory.Enqueue(new PlayerHistory(lastCount, clientnum)); playerCountStart = DateTime.Now; } @@ -493,21 +507,9 @@ namespace IW4MAdmin else nextMessage++; start = DateTime.Now; - //if (timesFailed <= 3) - // HB.Send(); - - String checkVer = new Connection("http://raidmax.org/IW4M/Admin/version.php").Read(); - double checkVerNum; - double.TryParse(checkVer, out checkVerNum); - if (checkVerNum != Program.Version && checkVerNum != 0 && !checkedForOutdate) - { - messages.Add("^5IW4M Admin ^7is outdated. Please ^5update ^7to version " + checkVerNum); - checkedForOutdate = true; - } - } - if ((DateTime.Now - lastPoll).Milliseconds > 750) + if ((DateTime.Now - lastPoll).Milliseconds > 300) { int numberRead = 0; int activeClients = 0; @@ -583,8 +585,18 @@ namespace IW4MAdmin #if DEBUG == false catch (Exception E) { - Log.Write("Something unexpected occured. Hopefully we can ignore it :)", Log.Level.All); - continue; + numExceptions++; + Log.Write("Unexpected error on \"" + hostname + "\"", Log.Level.Debug); + Log.Write("Error Message: " + E.Message, Log.Level.Debug); + Log.Write("Error Trace: " + E.StackTrace, Log.Level.Debug); + if (numExceptions < 30) + continue; + else + { + Log.Write("Maximum number of unhandled exceptions reached for \"" + hostname + "\"", Log.Level.Production); + events.Enqueue(new Event(Event.GType.Stop, "Monitoring stopping because of max exceptions reached", null, null, this)); + isRunning = false; + } } #endif @@ -596,20 +608,20 @@ namespace IW4MAdmin override public bool intializeBasics() { - try - { - // inject our dll - if (!Utilities.initalizeInterface(PID)) - { - Log.Write("Could not load IW4MAdmin interface!", Log.Level.Debug); - return false; - } + try + { + // inject our dll + if (!Utilities.initalizeInterface(PID)) + { + Log.Write("Could not load IW4MAdmin interface!", Log.Level.Debug); + return false; + } // basic info dvars - hostname = SharedLibrary.Utilities.stripColors(getDvar("sv_hostname").current); - mapname = getDvar("mapname").current; - IW_Ver = getDvar("shortversion").current; - maxClients = -1; + hostname = SharedLibrary.Utilities.stripColors(getDvar("sv_hostname").current); + mapname = getDvar("mapname").current; + IW_Ver = getDvar("shortversion").current; + maxClients = -1; Int32.TryParse(getDvar("party_maxplayers").current, out maxClients); if (maxClients == -1) @@ -618,46 +630,47 @@ namespace IW4MAdmin return false; } - Gametype = getDvar("g_gametype").current; + Gametype = getDvar("g_gametype").current; // important log variables - Basepath = getDvar("fs_basepath").current; - Mod = getDvar("fs_game").current; - logPath = getDvar("g_log").current; - int oneLog = -1; + Basepath = getDvar("fs_basepath").current; + Mod = getDvar("fs_game").current; + logPath = getDvar("g_log").current; + int oneLog = -1; Int32.TryParse(getDvar("iw4m_onelog").current, out oneLog); - if (oneLog == -1) - { - Log.Write("Could not get iw4m_onelog value", Log.Level.Debug); - return false; - } + if (oneLog == -1) + { + Log.Write("Could not get iw4m_onelog value", Log.Level.Debug); + return false; + } // our settings - setDvar("sv_kickBanTime", "3600"); // 1 hour - setDvar("g_logSync", "1"); // yas + setDvar("sv_kickBanTime", "3600"); // 1 hour + setDvar("g_logSync", "1"); // yas - if (Mod == String.Empty || oneLog == 1) - logPath = Basepath + '\\' + "m2demo" + '\\' + logPath; - else - logPath = Basepath + '\\' + Mod + '\\' + logPath; + if (Mod == String.Empty || oneLog == 1) + logPath = Basepath + '\\' + "m2demo" + '\\' + logPath; + else + logPath = Basepath + '\\' + Mod + '\\' + logPath; - if (!File.Exists(logPath)) - { - Log.Write("Gamelog `" + logPath + "` does not exist!", Log.Level.All); - return false; - } + if (!File.Exists(logPath)) + { + Log.Write("Gamelog `" + logPath + "` does not exist!", Log.Level.All); + return false; + } - logFile = new IFile(logPath); - Log.Write("Log file is " + logPath, Log.Level.Debug); - Log.Write("Now monitoring " + getName(), Log.Level.Production); - events.Enqueue(new Event(Event.GType.Start, "Server started", null, null, this)); - Bans = clientDB.getBans(); - return true; + logFile = new IFile(logPath); + Log.Write("Log file is " + logPath, Log.Level.Debug); + Log.Write("Now monitoring " + getName(), Log.Level.Production); + events.Enqueue(new Event(Event.GType.Start, "Server started", null, null, this)); + Bans = clientDB.getBans(); + return true; } + catch (Exception E) { - Log.Write("Error during initialization - " + E.Message +"--" + E.StackTrace, Log.Level.All); + Log.Write("Error during initialization - " + E.Message + "--" + E.StackTrace, Log.Level.All); return false; } } @@ -696,18 +709,6 @@ namespace IW4MAdmin if (E.Origin != E.Target) { - /*E.Origin.stats.Kills += 1; - E.Origin.stats.updateKDR(); - - E.Target.stats.Deaths += 1; - E.Target.stats.updateKDR(); - - //Skills.updateNewSkill(E.Origin, E.Target); - statDB.updatePlayer(E.Origin); - statDB.updatePlayer(E.Target); - - totalKills++;*/ - Log.Write(E.Origin.Name + " killed " + E.Target.Name + " with a " + E.Data, Log.Level.Debug); events.Enqueue(new Event(Event.GType.Death, E.Data, E.Target, null, this)); } @@ -720,7 +721,6 @@ namespace IW4MAdmin if (E.Type == Event.GType.Say) { - if (E.Data.Length < 2) // ITS A LIE! return false; @@ -738,12 +738,53 @@ namespace IW4MAdmin return false; } - if (E.Data.Substring(0, 1) != "!") // Not a command so who gives an F? + if (E.Data.Substring(0, 1) == "!" || E.Origin.Level == Player.Permission.Console) + { + Command C = E.isValidCMD(commands); + + if (C != null) + { + C = processCommand(E, C); + if (C != null) + { + if (C.needsTarget && E.Target == null) + { + Log.Write("Requested event requiring target does not have a target!", Log.Level.Debug); + return false; + } + + try + { + C.Execute(E); + } + + catch (Exception Except) + { + Log.Write(String.Format("A command request \"{0}\" generated an error.", C.Name, Log.Level.Debug)); + Log.Write(String.Format("Error Message: {0}", Except.Message), Log.Level.Debug); + Log.Write(String.Format("Error Trace: {0}", Except.StackTrace), Log.Level.Debug); + return false; + } + return true; + } + + else + { + Log.Write("Player didn't properly enter command - " + E.Origin.Name, Log.Level.Debug); + return true; + } + } + + else + E.Origin.Tell("You entered an invalid command!"); + } + + else // Not a command so who gives an F? { E.Data = SharedLibrary.Utilities.stripColors(SharedLibrary.Utilities.cleanChars(E.Data)); if (E.Data.Length > 50) E.Data = E.Data.Substring(0, 50) + "..."; - while (chatHistory.Count > Math.Ceiling((double)clientnum/2)) + while (chatHistory.Count > Math.Ceiling((double)clientnum / 2)) chatHistory.RemoveAt(0); chatHistory.Add(new Chat(E.Origin, E.Data, DateTime.Now)); @@ -751,32 +792,6 @@ namespace IW4MAdmin return true; } - Command C = E.isValidCMD(commands); - - if (C != null) - { - C = processCommand(E, C); - if (C != null) - { - if (C.needsTarget && E.Target == null) - { - Log.Write("Requested event requiring target does not have a target!", Log.Level.Debug); - return false; - } - C.Execute(E); - return true; - } - - else - { - Log.Write("Player didn't properly enter command - " + E.Origin.Name, Log.Level.Debug); - return true; - } - } - - else - E.Origin.Tell("You entered an invalid command!"); - return true; } @@ -784,35 +799,13 @@ namespace IW4MAdmin { Log.Write("New map loaded - " + clientnum + " active players", Log.Level.Debug); - Dictionary infoResponseDict = new Dictionary(); - String[] infoResponse = E.Data.Split('\\'); - - for (int i = 0; i < infoResponse.Length; i++) - { - if (i % 2 == 0 || infoResponse[i] == String.Empty) - continue; - infoResponseDict.Add(infoResponse[i], infoResponse[i + 1]); - } - - String newMapName = null; - infoResponseDict.TryGetValue("mapname", out newMapName); - - if (newMapName != null) - { - try - { - Map newMap = maps.Find(m => m.Name.Equals(newMapName)); - mapname = newMap.Alias; - } - - catch (Exception) - { - Log.Write(mapname + " doesn't appear to be in the maps.cfg", Log.Level.Debug); - } - } + String newMapName = getDvar("mapname").current; + Map newMap = maps.Find(m => m.Name.Equals(newMapName)); + if (newMap != null) + mapname = newMap.Alias; else - Log.Write("Could not get new mapname from InitGame line!", Log.Level.Debug); + mapname = newMapName; return true; } @@ -941,8 +934,6 @@ namespace IW4MAdmin commands.Add(new Find("find", "find player in database. syntax: !find ", "f", Player.Permission.SeniorAdmin, 1, false)); commands.Add(new Rules("rules", "list server rules. syntax: !rules", "r", Player.Permission.User, 0, false)); commands.Add(new PrivateMessage("privatemessage", "send message to other player. syntax: !pm ", "pm", Player.Permission.User, 2, true)); - //commands.Add(new _Stats("stats", "view your stats or another player's. syntax: !stats", "xlrstats", Player.Permission.User, 0, true)); - //commands.Add(new TopStats("topstats", "view the top 4 players on this server. syntax: !topstats", "xlrtopstats", Player.Permission.User, 0, false)); commands.Add(new Reload("reload", "reload configurations. syntax: !reload", "reload", Player.Permission.Owner, 0, false)); commands.Add(new Balance("balance", "balance teams. syntax !balance", "bal", Player.Permission.Moderator, 0, false)); commands.Add(new GoTo("goto", "teleport to selected player. syntax !goto", "go", Player.Permission.SeniorAdmin, 1, true)); @@ -962,7 +953,6 @@ namespace IW4MAdmin } //Objects - public Queue playerHistory; private Queue commandQueue; //Info diff --git a/Admin/lib/SharedLibary.dll b/Admin/lib/SharedLibary.dll index e2fd68cff..ce631ff94 100644 Binary files a/Admin/lib/SharedLibary.dll and b/Admin/lib/SharedLibary.dll differ diff --git a/Admin/plugins/SamplePlugin.dll b/Admin/plugins/SamplePlugin.dll index 01bc40695..df6183d27 100644 Binary files a/Admin/plugins/SamplePlugin.dll and b/Admin/plugins/SamplePlugin.dll differ diff --git a/Admin/plugins/Webfront Plugin.dll b/Admin/plugins/Webfront Plugin.dll deleted file mode 100644 index 448aa95fb..000000000 Binary files a/Admin/plugins/Webfront Plugin.dll and /dev/null differ diff --git a/Admin/plugins/WebfrontPlugin.dll b/Admin/plugins/WebfrontPlugin.dll new file mode 100644 index 000000000..38d4afa92 Binary files /dev/null and b/Admin/plugins/WebfrontPlugin.dll differ diff --git a/Admin/webfront/graph.html b/Admin/webfront/graph.html index 575ca3934..a1d26a701 100644 --- a/Admin/webfront/graph.html +++ b/Admin/webfront/graph.html @@ -55,3 +55,4 @@ function drawChart() { chart.draw(data, options); } +{{GRAPH}} diff --git a/Admin/webfront/header.html b/Admin/webfront/header.html index 81dac35b7..71dc83cda 100644 --- a/Admin/webfront/header.html +++ b/Admin/webfront/header.html @@ -414,8 +414,10 @@