diff --git a/IW4MAdmin.sln b/IW4MAdmin.sln index 7d8ee6125..21de08eb5 100644 --- a/IW4MAdmin.sln +++ b/IW4MAdmin.sln @@ -29,21 +29,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject _customcallbacks.gsc = _customcallbacks.gsc README.md = README.md - Admin\version.txt = Admin\version.txt + version.txt = version.txt EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Plugins\Tests\Tests.csproj", "{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebfrontCore", "WebfrontCore\WebfrontCore.csproj", "{65340D7D-5831-406C-ACAD-B13BA634BDE2}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{4101CDED-AF1E-4FCF-9194-BEA2E634016E}" - ProjectSection(SolutionItems) = preProject - Admin\Config\maps.cfg = Admin\Config\maps.cfg - Admin\Config\messages.cfg = Admin\Config\messages.cfg - Admin\Config\rules.cfg = Admin\Config\rules.cfg - Admin\Config\web.cfg = Admin\Config\web.cfg - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -350,7 +342,6 @@ Global {C9E821BF-23AD-4CB5-B7F9-B3B99B606650} = {26E8B310-269E-46D4-A612-24601F16065F} {1479DE87-ACB5-4046-81C8-A0BA5041227D} = {26E8B310-269E-46D4-A612-24601F16065F} {B8C2A759-8663-4F6F-9BA4-19595F5E12C1} = {26E8B310-269E-46D4-A612-24601F16065F} - {4101CDED-AF1E-4FCF-9194-BEA2E634016E} = {8C8F3945-0AEF-4949-A1F7-B18E952E50BC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {84F8F8E0-1F73-41E0-BD8D-BB6676E2EE87} diff --git a/Plugins/SimpleStats/Helpers/StatManager.cs b/Plugins/SimpleStats/Helpers/StatManager.cs index b083671b7..9ad73b60d 100644 --- a/Plugins/SimpleStats/Helpers/StatManager.cs +++ b/Plugins/SimpleStats/Helpers/StatManager.cs @@ -176,6 +176,12 @@ namespace StatsPlugin.Helpers { await AddStandardKill(attacker, victim); + if (victim == null) + { + Log.WriteError($"[AddScriptKill] Victim is null"); + return; + } + var statsSvc = ContextThreads[serverId]; var playerDetection = Servers[serverId].PlayerDetections[attacker.ClientNumber]; @@ -209,7 +215,7 @@ namespace StatsPlugin.Helpers if (victim == null) { - Log.WriteError($"Stats: Victim is null"); + Log.WriteError($"[AddStandardKill] Victim is null"); return; } diff --git a/Plugins/SimpleStats/Plugin.cs b/Plugins/SimpleStats/Plugin.cs index 180f6b333..345520f14 100644 --- a/Plugins/SimpleStats/Plugin.cs +++ b/Plugins/SimpleStats/Plugin.cs @@ -157,10 +157,6 @@ namespace StatsPlugin manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills)); manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", totalPlayTime)); - // WebService.PageList.Add(new ClientMessageJson()); - //WebService.PageList.Add(new ClientMessages()); - //WebService.PageList.Add(new LiveStats()); - ServerManager = manager; return Task.FromResult( diff --git a/SharedLibrary/Event.cs b/SharedLibrary/Event.cs index 5ad695e07..4e63d1623 100644 --- a/SharedLibrary/Event.cs +++ b/SharedLibrary/Event.cs @@ -131,7 +131,7 @@ namespace SharedLibrary if (removeTime.Contains("ScriptKill")) { - return new Event(GType.Script, String.Join(";", line), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[1].ConvertLong()), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[2].ConvertLong()), SV); + return new Event(GType.Script, String.Join(";", line), SV.Players.First(p => p != null && p.NetworkId == line[1].ConvertLong()), SV.Players.First(p => p != null && p.NetworkId == line[2].ConvertLong()), SV); } if (removeTime.Contains("ExitLevel")) diff --git a/WebfrontCore/Application/Config/maps.cfg b/WebfrontCore/Application/Config/maps.cfg new file mode 100644 index 000000000..14317d6b2 --- /dev/null +++ b/WebfrontCore/Application/Config/maps.cfg @@ -0,0 +1,44 @@ +mp_rust:Rust +mp_highrise:Highrise +mp_terminal:Terminal +mp_crash:Crash +mp_nightshift:Skidrow +mp_quarry:Quarry +mp_afghan:Afghan +mp_derail:Derail +mp_estate:Estate +mp_favela:Favela +mp_highrise:Highrise +mp_invasion:Invasion +mp_checkpoint:Karachi +mp_quarry:Quarry +mp_rundown:Rundown +mp_boneyard:Scrapyard +mp_nightshift:Skidrow +mp_subbase:Sub Base +mp_underpass:Underpass +mp_brecourt:Wasteland +mp_overgrown:Overgrown +mp_strike:Strike +mp_vacant:Vacant +mp_abandon:Carnival +mp_trailerpark:Trailer Park +mp_fuel2:Fuel +mp_storm:Storm +mp_complex:Bailout +mp_compact:Salvage +mp_nuked:Nuketown +iw4_credits:IW4 Credits +mp_killhouse:Killhouse +mp_bog_sh:Bog +mp_cargoship_sh:Freighter +mp_shipment:Shipment +mp_shipment_long:Shipment - Long +mp_rust_long:Rust - Long +mp_firingrange:Firing Range +mp_storm_spring:Chemical Plant +mp_fav_tropical:Favela - Tropical +mp_estate_tropical:Estate - Tropical +mp_crash_tropical:Crash - Tropical +mp_bloc_sh:Forgotten City +mp_raidmax:^1L^23^33^4T^5M^6A^75^8T^93^0R \ No newline at end of file diff --git a/WebfrontCore/Application/Config/messages.cfg b/WebfrontCore/Application/Config/messages.cfg new file mode 100644 index 000000000..c72ab1b78 --- /dev/null +++ b/WebfrontCore/Application/Config/messages.cfg @@ -0,0 +1,8 @@ +60 +Over ^5{{TOTALPLAYTIME}} ^7man hours have been played on this server! +This server uses ^5IW4M Admin v{{VERSION}} ^7get it at ^5raidmax.org/IW4MAdmin +^5IW4M Admin ^7sees ^5YOU! +This server has harvested the information of ^5{{TOTALPLAYERS}} ^7players! +Cheaters are ^1unwelcome ^7 on this server +Did you know 8/10 people agree with unverified statistics? +^5{{TOTALKILLS}} ^7innocent people have been murdered in this server! \ No newline at end of file diff --git a/WebfrontCore/Application/Config/rules.cfg b/WebfrontCore/Application/Config/rules.cfg new file mode 100644 index 000000000..71e9fe9a8 --- /dev/null +++ b/WebfrontCore/Application/Config/rules.cfg @@ -0,0 +1,6 @@ +Cheating/Exploiting is not allowed +Respect other players +Administrators have the final say +No Racism or excessive trolling +Keep grenade launcher use to a minimum +Balance teams at ALL times \ No newline at end of file diff --git a/WebfrontCore/Application/Config/web.cfg b/WebfrontCore/Application/Config/web.cfg new file mode 100644 index 000000000..499c2157c --- /dev/null +++ b/WebfrontCore/Application/Config/web.cfg @@ -0,0 +1,2 @@ +127.0.0.1 +80 \ No newline at end of file diff --git a/WebfrontCore/Application/Server.cs b/WebfrontCore/Application/Server.cs index b3c3e9559..58cbc0790 100644 --- a/WebfrontCore/Application/Server.cs +++ b/WebfrontCore/Application/Server.cs @@ -43,12 +43,14 @@ namespace IW4MAdmin if (polledPlayer.Name.Length < 3) { + Logger.WriteDebug($"Kicking {polledPlayer} because their name is too short"); await this.ExecuteCommandAsync($"clientkick {polledPlayer.ClientNumber} \"Your name must contain atleast 3 characters.\""); return false; } if (Players.FirstOrDefault(p => p != null && p.Name == polledPlayer.Name) != null) { + Logger.WriteDebug($"Kicking {polledPlayer} because their name is already in use"); await this.ExecuteCommandAsync($"clientkick {polledPlayer.ClientNumber} \"Your name is being used by someone else.\""); return false; } @@ -56,6 +58,7 @@ namespace IW4MAdmin if (polledPlayer.Name == "Unknown Soldier" || polledPlayer.Name == "UnknownSoldier") { + Logger.WriteDebug($"Kicking {polledPlayer} because their name is generic"); await this.ExecuteCommandAsync($"clientkick {polledPlayer.ClientNumber} \"Please change your name using /name.\""); return false; } @@ -99,6 +102,7 @@ namespace IW4MAdmin else if (existingAlias.Name == polledPlayer.Name) { client.CurrentAlias = existingAlias; + client.CurrentAliasId = existingAlias.AliasId; await Manager.GetClientService().Update(client); } player = client.AsPlayer(); diff --git a/WebfrontCore/WebfrontCore.csproj b/WebfrontCore/WebfrontCore.csproj index af95ca8d8..f4a2cc8c3 100644 --- a/WebfrontCore/WebfrontCore.csproj +++ b/WebfrontCore/WebfrontCore.csproj @@ -67,7 +67,7 @@ - + diff --git a/_customcallbacks.gsc b/_customcallbacks.gsc index 221ab8fe4..9eff3d2e5 100644 --- a/_customcallbacks.gsc +++ b/_customcallbacks.gsc @@ -14,9 +14,11 @@ Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vD { victim = self; _attacker = attacker; - if (!isDefined(attacker)) + if (!isPlayer(attacker) && isDefined(attacker.owner)) + _attacker = attacker.owner; + else if(!isPlayer(attacker) && sMeansOfDeath == "MOD_FALLING") _attacker = victim; - logPrint("ScriptKill;" + _attacker.guid + ";" + victim.guid + ";" + _attacker.origin + ";" + victim.origin + ";" + iDamage + ";" + sWeapon + ";" + sHitLoc + ";" + sMeansOfDeath + "\n"); + logPrint("ScriptKill;" + _attacker.guid + ";" + victim.guid + ";" + _attacker.origin + ";" + victim.origin + ";" + iDamage + ";" + sWeapon + ";" + sHitLoc + ";" + sMeansOfDeath + ";" + _attacker.angles + ";" + gettime() + "\n"); self maps\mp\gametypes\_damage::Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration ); } \ No newline at end of file diff --git a/version.txt b/version.txt new file mode 100644 index 000000000..10d1e17d9 --- /dev/null +++ b/version.txt @@ -0,0 +1,179 @@ +Version 1.6: +CHANGELOG: +-migrated from SQLite to EntityFramework +-migrated from kayak to ASP.Net Core MVC +-webfront redone using boostrap and now mobile-friendly +-added profile page to view client history +-got rid of pesky "error on character" message +-optimizations to commands +-report reason doesn't truncate if there's a space in the target name +-If multiple matches are found when finding a player, a list of matches is shown +-"special" characters are allowed in names and messages +-prune command demotes inactive admins (defaults to 30 days if no days are specified) +-confirmation message sent after kick +-paginated players page +-fixed aliases + +Version 1.5 +CHANGELOG: +-added back player history graphs (past 12 hours every 15 minutes) +-fixed issue with configurationmanager files and threading +-servers on webfront listed in descending player count +-fixed resolution of tempban times from console feedback +-reconfigured solution and projects to be correct debug/release and files copy properly +-started working on more advanced statistics +-all chat is stored +-word cloud displays most commonly used words on the server +-fixed misc issues + +VERSION 1.4 +CHANGELOG: +-works: with COD, WaW, MW3, BO1 (preliminary without extensive testing) +-fixed the issue with webfront chat history +-fixed console issue of spamming 'polling rate decreased' when server goes offline +-'unknown' admin in webfront defaults to 'IW4MAdmin' (refactoring mistake) +-streamlined the async server initialization +-added !ip command (prints a client's external IP) +-fixed up the findall command +-moved aliases to the manager +-added admins page to view privileged users +-fixed refactoring mistake with messages +-removes flag penality when unflagging a player +-fixed 'just now ago' on webfront +-webfront playerlist level colors are hidden to non admin users +-tempban length can now be specified (m, h, d, y) + +VERSION 1.3 +CHANGELOG: +-complete rewrite of lots of parts +-async EVERYTHING!!! +-designed to work with IW4X (funny how the GitHub description is now 100% accurate after almost 3 years) +-gsc features deprecated + +VERSION 1.2 +CHANGELOG: +-didn't think you'd see me again did you? +-lots of cleanup +-event api @ /events (documentation soon) +-gsc features work again ( excluding goto ) +-reworked plugin interface +-added automatic restart plugin +-fixed server stop event truncation +-penalty reasons don't show appeal website or "Player kicked" anymore +-fixed ban spacing issue +-masked flag now saved to database +-masked users level now hidden from !list +-fixed (crash?) with `!` in penalty reason +-remove repz features as now defunct +-banning from console now kicks the player if they are currently in game +-updating permissions from console now saves for in game players +-heartbeats re-enabled +-public banlist is now json format.. why didn't I do this originally? +-admins can execute commands directly from the web front +-better build management +-stats actually seems to be consistent + +VERSION 1.1 +CHANGELOG: +-fixed ban sorting ( and an overlooked bug ) +-added kicks, warnings and temp-bans to penalty list +-bans are now named penalties +-readded pubbans page http://127.0.0.1:1624/pubbans +-updated RepZ profile link +-added trusted group ( will need a new database or manual update ) +-reports capture screenshot (maybe) +-no more server duplicates on webfront when the server crashes ( was intentional ) +-warn reasons no longer show player's name + +VERSION 1.0 +CHANGELOG: +-first official stable release +-fixed last known error (due to web front passing invalid sql syntax) +-re-added stats. though still not working 100% +-added welcome plugin + +VERSION 0.9.5 +CHANGELOG: +-Major refactoring to support plugins +-*web front redux* +-lots of little fixes and stability improvements +-temporary removal of stats plugin as I perfect it + +VERSION 0.9.2 +CHANGELOG: +-fixed issues with crashing IW4 Servers + +VERSION: 0.9.1 +CHANGELOG: +-fixed issue with `history` timelime +-fixed issue with mapname not being updated +-fixed rare crash related to !list +-fixed topstats issues ( prevents cheaters from jumping to the top ) +-fixed webfront banlist not updating until tool restart +-now reads memory for player info! + +VERSION: 0.9 +CHANGELOG: +-webfront now displays player info and link to repz account +-webfront shows ips for authed admin ( determined by ip ) +-webfront now show chat and allows authed players to send ingame messages +-webfront now has public ban list http://127.0.0.1:1624/pubbans +-webfront now shows player history +-fixed time span issue in webfront +-fixed most recent ban always missing +-fixed crash when RCON stops responding and removing a player +-version on footer + +?VERSION: 0.8.1 +CHANGELOG: +-no longer have `world` client handle broken events +-hopefully fixed an issue with clients missing connection event +-fixed ban order in webfront +-fixed alias output duplicating +-fixed missing evade reason +-cleaned up project files + +VERSION: 0.8 +CHANGELOG: +-added mask command +-added baninfo command +-added alias command and removed redundant output from `find` +-added rcon command +-added webfront (http://127.0.0.1:1624) +-true skill is officially implemented +-find now shows last connect time +-noise on pm (if gsc_enabled) +-force 8 line chat height (if gsc_enabled) +-tell admins the number of reports on join +-enhanced ban tracking +-ip wait timeout added +-remove report on ban +-can't report yourself +-remove reported players when banned +-fixed rare crash with toadmins backend +-fixed crash when finding player stats that don't exist +-fixed a bug that caused owner command to reactivate only `creator` rank player existed +-fixed a bug that caused certain notifications to be sent to all players +-various small fixes + +VERSION: 0.7 +CHANGELOG: +-rcon tweaks +-so much stuff cant remember + +VERSION: 0.6 +CHANGELOG: +-stability fixes +-welcome has post-fixed connection indicator + +?VERSION: 0.5 +CHANGELOG: +-close config files after reading oops +-added reload command +-added macros! (Denoted by {{MACRO}} in server config right now only {{WISDOM}} and {{TOTALPLAYERS}}) +-added IP's (tracks and rebans new accounts on same banned ip)! +-aliases +-reworked database classes +-heartbeat gives running version +-player banned in find gives last ban reason +-reworked rcon yet again \ No newline at end of file