diff --git a/gamedata/Cs2Jailbreak.json b/gamedata/Cs2Jailbreak.json new file mode 100644 index 0000000..23f33a3 --- /dev/null +++ b/gamedata/Cs2Jailbreak.json @@ -0,0 +1,9 @@ +{ + "CBasePlayerController_SetPawn": { + "signatures": { + "library": "server", + "windows": "\\x44\\x88\\x4C\\x24\\x2A\\x55\\x57", + "linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x49\\x89\\xFC\\x53\\x48\\x89\\xF3\\x48\\x81\\xEC\\xC8\\x00\\x00\\x00" + } + } +} \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index 89ac2a9..6fe5946 100644 --- a/lang/en.json +++ b/lang/en.json @@ -9,6 +9,8 @@ "warden.laser_colour_command_desc": "!laser_colour - set laser colour", "warden.marker_colour_command_desc": "!laser_colour - set marker colour", "warden.swap_guard_desc": "Expected usage: !swap_guard ", + "warden.wsd_command_desc": "!wsd - Call a warden special day", + "warden.wsd_ff_command_desc": "!wsd - Call a warden friendly fire special day", "warden.warden_req_alive": "You must be alive to warden", "warden.warden_req_ct": "You must be a CT to warden", "warden.warden_taken": "{0} is already the warden", @@ -25,6 +27,44 @@ "warden.gun_menu_disabled": "Gun menu is disabled!", "warden.no_warden": "Their is no warden", "warden.time": "Warden has been active for {0} minutes", + "warden.fire_guard" : "Firing guards", + + "warden.take_warden_cmd": "w", + "warden.leave_warden_cmd": "uw", + "warden.remove_warden_cmd": "rw", + "warden.fire_guard_cmd": "fire_guard", + "warden.remove_marker_cmd": "remove_marker", + "warden.marker_colour_cmd": "marker_colour", + "warden.laser_colour_cmd": "laser_colour", + "warden.gun_cmd": "guns", + "warden.time_cmd": "wtime", + "warden.list_cmd": "wcommands", + "warden.warday_cmd": "wd", + "warden.swap_guard_cmd": "swap_guard", + "warden.no_block_cmd": "wub", + "warden.block_cmd": "wb", + "warden.force_open_cmd": "force_open", + "warden.force_close_cmd": "force_close", + "warden.sd_cmd": "wsd", + "warden.sd_ff_cmd": "wsd_ff", + + "logs.ct": "CT", + "logs.t": "T", + "logs.logs_cmd": "logs", + + "role.warden": "Warden", + "role.guard": "Guard", + "role.prisoner": "Prisoner", + "role.rebel": "Rebel", + "role.spectator": "Spectator", + "role.unknown": "Unknown", + + "logs.format.damage": "{0} ({1}) damaged {2} ({3}) for {4} damage", + "logs.format.damage_self": "The world damaged {0} ({1}) for {2} damage", + "logs.format.kill": "{0} ({1}) killed {2} ({3})", + "logs.format.kill_self": "The world killed {0} ({1})", + "logs.format.button": "{0} ({1}) pressed button {2}->{3}", + "logs.format.grenade": "{0} ({1}) threw a {2}", "mute.thirty": "All t's are muted for the first 30 seconds", "mute.speak_quietly": "T's may now speak quietly", @@ -65,6 +105,11 @@ "sd.tank_start": "Tank day started", "sd.tank_end": "Tank day ended", "sd.tank": "{0} is the tank!", + + "sd.start_cmd": "sd", + "sd.start_ff_cmd": "sd_ff", + "sd.cancel_cmd": "sd_cancel", + "lr.rebel_last": "You must be the last player alive to rebel", "lr.riot_start": "A riot has started! CT's have 15 seconds to hide", @@ -78,5 +123,9 @@ "lr.player_rebel": "{0} is a rebel!", "lr.knife_rebel": "{0} is knife a rebel!", "lr.ready": "Last request is available! Type !lr", - "lr.wait": "Please wait 15 seconds into the round before starting an lr" + "lr.wait": "Please wait 15 seconds into the round before starting an lr", + + "lr.cancel_lr_cmd": "cancel_lr", + "lr.start_lr_cmd": "lr", + "lr.stats_cmd": "lr_stats" } diff --git a/src/Debug.cs b/src/Debug.cs index c1d1744..84d273c 100644 --- a/src/Debug.cs +++ b/src/Debug.cs @@ -66,6 +66,16 @@ public static void hide_weapon_cmd(CCSPlayerController? invoke, CommandInfo comm invoke.hide_weapon(); } + [RequiresPermissions("@jail/debug")] + public static void wsd_enable_cmd(CCSPlayerController? invoke, CommandInfo command) + { + if(invoke != null && invoke.is_valid()) + { + invoke.PrintToChat("enable wsd"); + JailPlugin.sd.wsd_round = 0x7000_0000; + } + } + [RequiresPermissions("@jail/debug")] public static void is_muted_cmd(CCSPlayerController? invoke, CommandInfo command) { diff --git a/src/Jail.cs b/src/Jail.cs index 3032b9a..9daec8e 100644 --- a/src/Jail.cs +++ b/src/Jail.cs @@ -65,6 +65,8 @@ public class JailConfig : BasePluginConfig [JsonPropertyName("warden_force_removal")] public bool warden_force_removal { get; set; } = true; + [JsonPropertyName("strip_spawn_weapons")] + public bool strip_spawn_weapons { get; set; } = true; [JsonPropertyName("warday_guns")] public bool warday_guns { get; set; } = false; @@ -121,6 +123,9 @@ public class JailConfig : BasePluginConfig [JsonPropertyName("rebel_requirehit")] public bool rebel_requirehit { get; set; } = false; + + [JsonPropertyName("wsd_round")] + public int wsd_round { get; set; } = 50; } // main plugin file, controls central hooking @@ -199,11 +204,12 @@ public static void purge_player_stats(CCSPlayerController? player) public override string ModuleName => "CS2 Jailbreak - destoer"; - public override string ModuleVersion => "v0.2.2"; + public override string ModuleVersion => "v1.2.2"; public override void Load(bool hotReload) { global_ctx = this; + logs = new Logs(this); register_commands(); @@ -216,6 +222,7 @@ public override void Load(bool hotReload) Console.WriteLine("Sucessfully started JB"); AddTimer(Warden.LASER_TIME,warden.laser_tick,CSTimer.TimerFlags.REPEAT); + } void stat_db_reload() @@ -241,6 +248,8 @@ public void OnConfigParsed(JailConfig config) warden.warday.config = config; JailPlayer.config = config; + sd.config = config; + lr.lr_config_reload(); stat_db_reload(); } @@ -254,40 +263,52 @@ void register_listener() }); } + void add_localized_cmd(String base_name,String desc,CommandInfo.CommandCallback callback) + { + AddCommand("css_" + Localizer[base_name],desc,callback); + } + void register_commands() { // reg warden comamnds - AddCommand("css_w", "take warden", warden.take_warden_cmd); - AddCommand("css_uw", "leave warden", warden.leave_warden_cmd); - AddCommand("css_rw", "remove warden", warden.remove_warden_cmd); - AddCommand("css_clear_marker", "remove warden marker",warden.remove_marker_cmd); + add_localized_cmd("warden.take_warden_cmd", "take warden", warden.take_warden_cmd); + add_localized_cmd("warden.leave_warden_cmd", "leave warden", warden.leave_warden_cmd); + add_localized_cmd("warden.remove_warden_cmd", "remove warden", warden.remove_warden_cmd); + add_localized_cmd("warden.remove_marker_cmd","remove warden marker",warden.remove_marker_cmd); + + add_localized_cmd("warden.marker_colour_cmd", "set marker colour", warden.marker_colour_cmd); + add_localized_cmd("warden.laser_colour_cmd", "set laser colour", warden.laser_colour_cmd); - AddCommand("css_wub","warden : disable block",warden.wub_cmd); - AddCommand("css_wb","warden : enable block",warden.wb_cmd); - AddCommand("css_marker_colour", "set laser colour", warden.marker_colour_cmd); - AddCommand("css_laser_colour", "set laser colour", warden.laser_colour_cmd); + add_localized_cmd("warden.no_block_cmd","warden : disable block",warden.wub_cmd); + add_localized_cmd("warden.block_cmd","warden : enable block",warden.wb_cmd); - AddCommand("css_swap_guard","admin : move a player to ct",warden.swap_guard_cmd); + add_localized_cmd("warden.sd_cmd","warden : call a special day",sd.warden_sd_cmd); + add_localized_cmd("warden.sd_ff_cmd","warden : call a friendly fire special day",sd.warden_sd_ff_cmd); - AddCommand("css_wd","warden : start warday",warden.warday_cmd); - AddCommand("css_wcommands", "warden : show all commands",warden.cmd_info); - AddCommand("css_wtime", "how long as warden been active?", warden.warden_time_cmd); + add_localized_cmd("warden.swap_guard","admin : move a player to ct",warden.swap_guard_cmd); + add_localized_cmd("warden.warday_cmd","warden : start warday",warden.warday_cmd); + add_localized_cmd("warden.list_cmd", "warden : show all commands",warden.cmd_info); + add_localized_cmd("warden.time_cmd","how long as warden been active?",warden.warden_time_cmd); - AddCommand("css_guns","give ct guns",warden.cmd_ct_guns); - AddCommand("css_force_open","force open every door and vent",warden.force_open_cmd); - AddCommand("css_force_close","force close every door",warden.force_close_cmd); + add_localized_cmd("warden.gun_cmd","give ct guns",warden.cmd_ct_guns); + + add_localized_cmd("warden.force_open_cmd","force open every door and vent",warden.force_open_cmd); + add_localized_cmd("warden.force_close_cmd","force close every door",warden.force_close_cmd); + + add_localized_cmd("warden.fire_guard_cmd","admin : Remove all guards apart from warden",warden.fire_guard_cmd); // reg lr commands - AddCommand("css_lr","start an lr",lr.lr_cmd); - AddCommand("css_cancel_lr","admin : cancel lr",lr.cancel_lr_cmd); - AddCommand("css_lr_stats","list lr stats",jail_stats.lr_stats_cmd); + add_localized_cmd("lr.start_lr_cmd","start an lr",lr.lr_cmd); + add_localized_cmd("lr.cancel_lr_cmd","admin : cancel lr",lr.cancel_lr_cmd); + add_localized_cmd("lr.stats_cmd","list lr stats",jail_stats.lr_stats_cmd); // reg sd commands - AddCommand("css_sd","start a sd",sd.sd_cmd); - AddCommand("css_sd_ff","start a ff sd",sd.sd_ff_cmd); - AddCommand("css_cancel_sd","cancel an sd",sd.cancel_sd_cmd); + add_localized_cmd("sd.start_cmd","start a sd",sd.sd_cmd); + add_localized_cmd("sd.start_ff_cmd","start a ff sd",sd.sd_ff_cmd); + add_localized_cmd("sd.cancel_cmd","cancel an sd",sd.cancel_sd_cmd); + add_localized_cmd("logs.logs_cmd", "show round logs", logs.LogsCommand); AddCommandListener("jointeam",join_team); // debug @@ -318,7 +339,7 @@ public HookResult join_team(CCSPlayerController? invoke, CommandInfo command) { jail_player.load_player(invoke); } - + if(!warden.join_team(invoke,command)) { return HookResult.Stop; @@ -359,8 +380,6 @@ void register_hook() AddCommandListener("player_ping", CommandListener_RadioCommand); - AddCommandListener("player_ping", CommandListener_RadioCommand); - // TODO: need to hook weapon drop } @@ -401,6 +420,7 @@ HookResult OnButtonPressed(CEntityIOOutput output, String name, CEntityInstance if(player != null && player.is_valid() && ent != null && ent.IsValid) { Lib.print_console_all($"{player.PlayerName} pressed button '{ent.Entity?.Name}' -> '{output?.Connections?.TargetDesc}'",true); + logs.AddLocalized(player, "logs.format.button", ent.Entity?.Name ?? "Unlabeled", output?.Connections?.TargetDesc ?? "None"); } return HookResult.Continue; @@ -419,6 +439,7 @@ HookResult OnGrenadeThrown(EventGrenadeThrown @event, GameEventInfo info) { lr.grenade_thrown(player); sd.grenade_thrown(player); + logs.AddLocalized(player, "logs.format.grenade", @event.Weapon); } return HookResult.Continue; @@ -657,4 +678,5 @@ public static String localise(string name,params Object[] args) public static LastRequest lr = new LastRequest(); public static SpecialDay sd = new SpecialDay(); public static JailStats jail_stats = new JailStats(); + public static Logs logs; } \ No newline at end of file diff --git a/src/LastRequest/Dodgeball.cs b/src/LastRequest/Dodgeball.cs index 37473fa..c2ad917 100644 --- a/src/LastRequest/Dodgeball.cs +++ b/src/LastRequest/Dodgeball.cs @@ -59,7 +59,7 @@ public override void player_hurt(int damage, int health, int hitgroup) public override void grenade_thrown() { CCSPlayerController? player = Utilities.GetPlayerFromSlot(player_slot); - Lib.give_event_nade_delay(player,1.4f,"weapon_flashbang"); + give_lr_nade_delay(1.4f,"weapon_flashbang"); } public override void ent_created(CEntityInstance entity) diff --git a/src/LastRequest/Grenade.cs b/src/LastRequest/Grenade.cs index 1d4dcc6..6c7b68d 100644 --- a/src/LastRequest/Grenade.cs +++ b/src/LastRequest/Grenade.cs @@ -50,6 +50,6 @@ public override void grenade_thrown() { CCSPlayerController? player = Utilities.GetPlayerFromSlot(player_slot); player.strip_weapons(true); - Lib.give_event_nade_delay(player,1.4f,"weapon_hegrenade"); + give_lr_nade_delay(1.4f,"weapon_hegrenade"); } } \ No newline at end of file diff --git a/src/LastRequest/LRBase.cs b/src/LastRequest/LRBase.cs index 1e6e5df..70c7e23 100644 --- a/src/LastRequest/LRBase.cs +++ b/src/LastRequest/LRBase.cs @@ -226,6 +226,28 @@ public virtual bool weapon_equip(String name) return (winner,loser,winner_lr); } + + public void give_lr_nade_delay(float delay, String name) + { + if(JailPlugin.global_ctx == null) + { + return; + } + + JailPlugin.global_ctx.AddTimer(delay,() => + { + CCSPlayerController? player = Utilities.GetPlayerFromSlot(player_slot); + + // need to double check LR is actually still active... + if(player != null && player.is_valid_alive() && manager.in_lr(player)) + { + //Server.PrintToChatAll("give nade"); + player.strip_weapons(true); + player.GiveNamedItem(name); + } + }); + } + static public void print_countdown(LRBase lr, int delay) { if(lr.partner == null) diff --git a/src/LastRequest/Rebel.cs b/src/LastRequest/Rebel.cs index 573e36d..6974fc4 100644 --- a/src/LastRequest/Rebel.cs +++ b/src/LastRequest/Rebel.cs @@ -40,7 +40,7 @@ public void rebel_guns(CCSPlayerController player, ChatMenuOption option) player.strip_weapons(); - player.GiveNamedItem("weapon_" + Lib.gun_give_name(option.Text)); + player.GiveNamedItem(Lib.gun_give_name(option.Text)); player.GiveNamedItem("weapon_deagle"); player.GiveNamedItem("item_assaultsuit"); diff --git a/src/Lib.cs b/src/Lib.cs index 55119d1..28872b0 100644 --- a/src/Lib.cs +++ b/src/Lib.cs @@ -302,12 +302,8 @@ static public void strip_weapons(this CCSPlayerController? player, bool remove_k return; } - // buggy on windows (Wrong gamedata issue) - if(!is_windows()) - { - player.RemoveWeapons(); - } - + player.RemoveWeapons(); + // dont remove knife its buggy if(!remove_knife) { @@ -688,10 +684,10 @@ static void give_menu_weapon(CCSPlayerController player, ChatMenuOption option) player.strip_weapons(); // give their desired guns with lots of reserve ammo - player.GiveNamedItem("weapon_" + gun_give_name(option.Text)); + player.GiveNamedItem(gun_give_name(option.Text)); player.GiveNamedItem("weapon_deagle"); - CBasePlayerWeapon? primary = Lib.find_weapon(player,gun_give_name(option.Text)); + CBasePlayerWeapon? primary = Lib.find_weapon(player,GUN_LIST[option.Text]); primary.set_ammo(-1,999); CBasePlayerWeapon? secondary = Lib.find_weapon(player,"deagle"); @@ -700,35 +696,27 @@ static void give_menu_weapon(CCSPlayerController player, ChatMenuOption option) player.GiveNamedItem("item_assaultsuit"); } - static String[] GUN_LIST = - { - "ak47", "m4a1_silencer","nova", - "p90", "m249", "mp5sd", - "galilar", "sg556","bizon", "aug", - "famas", "xm1014","ssg08","awp" - - }; - - static String[] GUN_NAMES = - { - "AK47","M4","M3","P90","M249","MP5", - "FAL","SG556","BIZON","AUG", - "FAMAS","XM1014","SCOUT","AWP" + static Dictionary GUN_LIST = new Dictionary() + { + {"AK47","ak47"}, + {"M4","m4a1_silencer"}, + {"M3","nova"}, + {"P90","p90"}, + {"M249","m249"}, + {"MP5","mp5sd"}, + {"FAL","galilar"}, + {"SG556","sg556"}, + {"BIZON","bizon"}, + {"AUG","aug"}, + {"FAMAS","famas"}, + {"XM1014","xm1014"}, + {"SCOUT","ssg08"}, + {"AWP", "awp"}, }; - public static String gun_give_name(String name) { - // TODO: a linear scan shouldn't matter on a list this small - for(int i = 0; i < GUN_NAMES.Count(); i++) - { - if(name == GUN_NAMES[i]) - { - return GUN_LIST[i]; - } - } - - return ""; + return "weapon_" + GUN_LIST[name]; } static public void gun_menu_internal(this CCSPlayerController? player, bool no_awp, Action callback) @@ -742,8 +730,10 @@ static public void gun_menu_internal(this CCSPlayerController? player, bool no_a var gun_menu = new ChatMenu("Gun Menu"); - foreach(var weapon_name in GUN_NAMES) + foreach(var weapon_pair in GUN_LIST) { + var weapon_name = weapon_pair.Key; + if(no_awp && weapon_name == "awp") { continue; diff --git a/src/SpecialDay/SpecialDay.cs b/src/SpecialDay/SpecialDay.cs index a833ad5..0a29c3e 100644 --- a/src/SpecialDay/SpecialDay.cs +++ b/src/SpecialDay/SpecialDay.cs @@ -54,6 +54,8 @@ public void round_end() public void round_start() { + // increment our round counter + wsd_round += 1; end_sd(); } @@ -70,6 +72,14 @@ public void setup_sd(CCSPlayerController? invoke, ChatMenuOption option) return; } + // invoked as warden + // reset the round counter so they can't do it again + if(wsd_command) + { + wsd_round = 0; + } + + String name = option.Text; switch(name) @@ -317,7 +327,7 @@ public void sd_rig_cmd(CCSPlayerController? player,CommandInfo command) public void sd_cmd(CCSPlayerController? player,CommandInfo command) { override_ff = false; - + wsd_command = false; sd_cmd_internal(player,command); } @@ -325,8 +335,42 @@ public void sd_cmd(CCSPlayerController? player,CommandInfo command) public void sd_ff_cmd(CCSPlayerController? player,CommandInfo command) { override_ff = true; + wsd_command = false; + sd_cmd_internal(player,command); + } + public void warden_sd_cmd_internal(CCSPlayerController? player,CommandInfo command) + { + if(!JailPlugin.is_warden(player)) + { + player.announce(SPECIALDAY_PREFIX,"You must be a warden to use this command"); + return; + } + + // Not ready yet + if(wsd_round < config.wsd_round) + { + player.announce(SPECIALDAY_PREFIX,$"Please wait {config.wsd_round - wsd_round} more rounds"); + return; + } + + // Go! + wsd_command = true; sd_cmd_internal(player,command); + } + + public void warden_sd_cmd(CCSPlayerController? player,CommandInfo command) + { + override_ff = false; + + warden_sd_cmd_internal(player,command); + } + + public void warden_sd_ff_cmd(CCSPlayerController? player,CommandInfo command) + { + override_ff = true; + + warden_sd_cmd_internal(player,command); } public enum SDType @@ -362,6 +406,12 @@ public enum SDType int delay = 15; + public int wsd_round = 0; + + // NOTE: if we cared we would make this per player + // so we can't get weird conflicts, but its not a big deal + bool wsd_command = false; + SDBase? active_sd = null; bool override_ff = false; @@ -370,5 +420,7 @@ public enum SDType SDType type = SDType.NONE; + public JailConfig config = new JailConfig(); + TeamSave team_save = new TeamSave(); }; \ No newline at end of file diff --git a/src/Stats.cs b/src/Stats.cs index fa35e9a..95cd738 100644 --- a/src/Stats.cs +++ b/src/Stats.cs @@ -122,7 +122,6 @@ async void insert_player(String steam_id, String player_name) { var database = await connect_db(); - if(database == null) { return; @@ -147,7 +146,7 @@ async void insert_player(String steam_id, String player_name) public void inc_db(CCSPlayerController? player,LastRequest.LRType type, bool win) { - if(player == null || !player.is_valid() || type == LastRequest.LRType.NONE) + if(player == null || !player.is_valid() || type == LastRequest.LRType.NONE || player.IsBot) { return; } diff --git a/src/Warden/JailPlayer.cs b/src/Warden/JailPlayer.cs index d6d9be0..3f3e1ef 100644 --- a/src/Warden/JailPlayer.cs +++ b/src/Warden/JailPlayer.cs @@ -12,6 +12,7 @@ using CounterStrikeSharp.API.Modules.Entities.Constants; using System.Drawing; using Microsoft.Data.Sqlite; +using McMaster.NETCore.Plugins; public class JailPlayer @@ -35,11 +36,12 @@ public static void setup_db() { "ALTER TABLE config ADD COLUMN laser_colour varchar(64) DEFAULT 'Cyan'", "ALTER TABLE config ADD COLUMN marker_colour varchar(64) DEFAULT 'Cyan'", + "ALTER TABLE config ADD COLUMN ct_gun varchar(64) DEFAULT 'M4'", }; // start populating our fields - foreach(var cmd in col_cmd) + foreach (var cmd in col_cmd) { var col = connection.CreateCommand(); col.CommandText = cmd; @@ -50,20 +52,19 @@ public static void setup_db() { col.ExecuteNonQuery(); } - - catch {} + catch { } } } } // Actually print these, creation should not fail - catch(Exception ex) + catch (Exception ex) { Console.WriteLine(ex.ToString()); } } - async Task update_player_db(String steam_id,String name,String value) + async Task update_player_db(String steam_id, String name, String value) { try { @@ -74,12 +75,11 @@ async Task update_player_db(String steam_id,String name,String value) // modify one of the setting fields using var update = connection.CreateCommand(); update.CommandText = $"UPDATE config SET {name} = '{value}' WHERE steam_id = @steam_id"; - update.Parameters.AddWithValue("@steam_id",steam_id); + update.Parameters.AddWithValue("@steam_id", steam_id); await update.ExecuteNonQueryAsync(); } - } - + } catch (Exception ex) { Console.WriteLine(ex.ToString()); @@ -90,23 +90,22 @@ async Task insert_player_db(String steam_id) { using (var connection = new SqliteConnection("Data Source=destoer_config.sqlite")) { - try + try { await connection.OpenAsync(); // add a new steam id using var insert_player = connection.CreateCommand(); insert_player.CommandText = "INSERT OR IGNORE INTO config (steam_id) VALUES (@steam_id)"; - insert_player.Parameters.AddWithValue("@steam_id",steam_id); + insert_player.Parameters.AddWithValue("@steam_id", steam_id); await insert_player.ExecuteNonQueryAsync(); - } - + } catch (Exception ex) { Console.WriteLine(ex.ToString()); } - } + } } async Task load_player_db(String steam_id) @@ -122,15 +121,16 @@ async Task load_player_db(String steam_id) // query steamid query_steam_id.CommandText = "SELECT * FROM config WHERE steam_id = @steam_id"; - query_steam_id.Parameters.AddWithValue("@steam_id",steam_id); + query_steam_id.Parameters.AddWithValue("@steam_id", steam_id); + + using var reader = await query_steam_id.ExecuteReaderAsync(); - using var reader = await query_steam_id.ExecuteReaderAsync(); - - if(reader.Read()) + if (reader.Read()) { // just override this - laser_colour = Lib.LASER_CONFIG_MAP[(String)reader["laser_colour"]]; + laser_colour = Lib.LASER_CONFIG_MAP[(String)reader["laser_colour"]]; marker_colour = Lib.LASER_CONFIG_MAP[(String)reader["marker_colour"]]; + ct_gun = (String)reader["ct_gun"]; // don't try reloading the player cached = true; @@ -154,12 +154,14 @@ async Task load_player_db(String steam_id) public void load_player(CCSPlayerController? player) { - if(player == null || !player.is_valid()) + if (player == null || !player.is_valid()) { return; } - if(cached) + // The database has allready been read before + // there is not need to do it again + if (cached) { return; } @@ -175,7 +177,7 @@ public void load_player(CCSPlayerController? player) public void update_player(CCSPlayerController? player, String name, String value) { - if(player == null || !player.is_valid()) + if (player == null || !player.is_valid()) { return; } @@ -185,36 +187,36 @@ public void update_player(CCSPlayerController? player, String name, String value // make sure this doesn't block the main thread Task.Run(async () => { - await update_player_db(steam_id,name,value); + await update_player_db(steam_id, name, value); }); } - public void set_laser(CCSPlayerController? player,String value) + public void set_laser(CCSPlayerController? player, String value) { - if(player == null || !player.is_valid()) + if (player == null || !player.is_valid()) { return; } - player.announce(Warden.WARDEN_PREFIX,$"Laser colour set to {value}"); + player.announce(Warden.WARDEN_PREFIX, $"Laser colour set to {value}"); laser_colour = Lib.LASER_CONFIG_MAP[value]; // save back to the db too - update_player(player,"laser_colour",value); + update_player(player, "laser_colour", value); } - public void set_marker(CCSPlayerController? player,String value) + public void set_marker(CCSPlayerController? player, String value) { - if(player == null || !player.is_valid()) + if (player == null || !player.is_valid()) { return; } - player.announce(Warden.WARDEN_PREFIX,$"Marker colour set to {value}"); + player.announce(Warden.WARDEN_PREFIX, $"Marker colour set to {value}"); marker_colour = Lib.LASER_CONFIG_MAP[value]; // save back to the db too - update_player(player,"marker_colour",value); + update_player(player, "marker_colour", value); } public void purge_round() @@ -229,72 +231,76 @@ public void reset() // TODO: reset client specific settings laser_colour = Lib.CYAN; marker_colour = Lib.CYAN; + ct_gun = "M4"; } public void set_rebel(CCSPlayerController? player) { - if(JailPlugin.event_active()) + // allready a rebel don't care + if (is_rebel) + { + return; + } + + if (JailPlugin.event_active()) { return; } // ignore if they are in lr - if(JailPlugin.global_ctx != null) + if (JailPlugin.lr.in_lr(player)) { - if(JailPlugin.lr.in_lr(player)) - { - return; - } + return; } // dont care if player is invalid - if(!player.is_valid() || player == null) + if (!player.is_valid() || player == null) { return; } // on T with no warday or sd active - if(player.TeamNum == Lib.TEAM_T) + if (player.TeamNum == Lib.TEAM_T) { - if(config.colour_rebel) + if (config.colour_rebel) { + Lib.announce(REBEL_PREFIX, $"{player.PlayerName} is a rebel"); player.set_colour(Lib.RED); } is_rebel = true; } } - public void rebel_death(CCSPlayerController? player,CCSPlayerController? killer) + public void rebel_death(CCSPlayerController? player, CCSPlayerController? killer) { // event active dont care - if(JailPlugin.event_active()) + if (JailPlugin.event_active()) { return; } // players aernt valid dont care - if(killer == null || player == null || !player.is_valid() || !killer.is_valid()) + if (killer == null || player == null || !player.is_valid() || !killer.is_valid()) { return; } // print death if player is rebel and killer on CT - if(is_rebel && killer.TeamNum == Lib.TEAM_CT) + if (is_rebel && killer.TeamNum == Lib.TEAM_CT) { Lib.log($"rebel {player.PlayerName} killed by {killer.PlayerName}"); - Lib.localise_announce($" {ChatColors.Green}[REBEL]: {ChatColors.White}","rebel.kill",killer.PlayerName,player.PlayerName); + Lib.localise_announce(REBEL_PREFIX, "rebel.kill", killer.PlayerName, player.PlayerName); } } public void rebel_weapon_fire(CCSPlayerController? player, String weapon) { - if(config.rebel_requirehit) + if (config.rebel_requirehit) { return; } - // ignore weapons players are meant to have - if(!weapon.Contains("knife") && !weapon.Contains("c4")) + if (!weapon.Contains("knife") && !weapon.Contains("c4")) { if(config.rebel_requirehit) return; @@ -304,30 +310,49 @@ public void rebel_weapon_fire(CCSPlayerController? player, String weapon) public void player_hurt(CCSPlayerController? player, CCSPlayerController? attacker, int health, int damage) { - if(player == null || attacker == null || !player.is_valid() || !attacker.is_valid()) + if (player == null || !player.is_valid()) + return; + + bool isWorld = attacker == null || !attacker.is_valid(); + + string localKey = health > 0 ? "logs.format.damage" : "logs.format.kill"; + if (isWorld) + { + JailPlugin.logs.AddLocalized(player, localKey + "_self", damage); + } + else + { + JailPlugin.logs.AddLocalized(player, attacker!, localKey, damage); + } + + if (isWorld) { return; } // ct hit by T they are a rebel - if(player.is_ct() && attacker.is_t()) + if (player.is_ct() && attacker.is_t()) { set_rebel(attacker); } // log any ct damage - else if(attacker.is_ct()) + else if (attacker.is_ct()) { //Lib.print_console_all($"CT {attacker.PlayerName} hit {player.PlayerName} for {damage}"); } } + public static readonly String REBEL_PREFIX = $" {ChatColors.Green}[REBEL]: {ChatColors.White}"; + public static JailConfig config = new JailConfig(); public Color laser_colour { get; private set; } = Lib.CYAN; public Color marker_colour { get; private set; } = Lib.CYAN; bool cached = false; + public String ct_gun = "M4"; + public bool is_rebel = false; }; diff --git a/src/Warden/Logs.cs b/src/Warden/Logs.cs new file mode 100644 index 0000000..453644a --- /dev/null +++ b/src/Warden/Logs.cs @@ -0,0 +1,106 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Commands; +using CounterStrikeSharp.API.Modules.Utils; + +public class Logs +{ + private readonly List logs = new List(); + private readonly BasePlugin plugin; + private long roundStart = -1; + + public Logs(BasePlugin plugin) + { + this.plugin = plugin; + plugin.RegisterEventHandler(OnRoundStart); + plugin.RegisterEventHandler(OnRoundEnd); + } + + public void LogsCommand(CCSPlayerController? executor, CommandInfo info) + { + printLogs(executor); + } + + private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) + { + foreach (CCSPlayerController player in Utilities.GetPlayers()) + { + if (!player.IsValid || player.IsBot || player.IsHLTV) continue; + printLogs(player); + } + logs.Clear(); + return HookResult.Continue; + } + + private void printLogs(CCSPlayerController? player) + { + if (player == null) + { + printLogs(Server.PrintToConsole); + } + else + { + printLogs(player.PrintToConsole); + } + } + + private void printLogs(Delegate printFunction) + { + printFunction.DynamicInvoke("********************************"); + printFunction.DynamicInvoke("***** BEGIN JAILBREAK LOGS *****"); + printFunction.DynamicInvoke("********************************"); + foreach (string log in logs) + { + printFunction.DynamicInvoke(log); + } + printFunction.DynamicInvoke("********************************"); + printFunction.DynamicInvoke("****** END JAILBREAK LOGS ******"); + printFunction.DynamicInvoke("********************************"); + } + + private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) + { + roundStart = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + return HookResult.Continue; + } + + public void Add(string log) + { + TimeSpan span = TimeSpan.FromSeconds(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - roundStart); + string format = $"[{span:mm':'ss}] {log}"; + logs.Add(format); + } + + public void AddLocalized(string key, params object[] args) + { + Add(plugin.Localizer[key, args]); + } + + public void AddLocalized(CCSPlayerController source, string key, params object[] args) + { + args = args.Prepend(GetPlayerRole(source)).Prepend(source.PlayerName).ToArray(); + Add(plugin.Localizer[key, args]); + } + + public void AddLocalized(CCSPlayerController source, CCSPlayerController target, string key, params object[] args) + { + args = args.Prepend(GetPlayerRole(target)).Prepend(target.PlayerName).Prepend(GetPlayerRole(source)).Prepend(source.PlayerName).ToArray(); + Add(plugin.Localizer[key, args]); + } + + + public String GetPlayerRole(CCSPlayerController player) + { + switch ((CsTeam)player.TeamNum) + { + case CsTeam.Spectator: + return plugin.Localizer["role.spectator"]; + case CsTeam.CounterTerrorist: + return plugin.Localizer[JailPlugin.warden.is_warden(player) ? "role.warden" : "role.guard"]; + case CsTeam.Terrorist: + return plugin.Localizer[JailPlugin.warden.jail_players[player.Slot].is_rebel ? "role.rebel" : "role_prisoner"]; + default: + return plugin.Localizer["role.unknown"]; + } + } +} \ No newline at end of file diff --git a/src/Warden/Warden.cs b/src/Warden/Warden.cs index 1d1dba6..ce77af1 100644 --- a/src/Warden/Warden.cs +++ b/src/Warden/Warden.cs @@ -59,6 +59,8 @@ public void set_warden(int? new_slot_opt) // change player color! player.set_colour(Color.FromArgb(255, 0, 0, 255)); + + JailPlugin.logs.AddLocalized("warden.took_warden", player.PlayerName); } public bool is_warden(CCSPlayerController? player) @@ -82,6 +84,7 @@ public void remove_warden() player.set_colour(Color.FromArgb(255, 255, 255, 255)); Lib.localise_announce(WARDEN_PREFIX,"warden.removed",player.PlayerName); + JailPlugin.logs.AddLocalized("warden.removed", player.PlayerName); } remove_warden_internal(); @@ -276,6 +279,8 @@ public void cmd_info(CCSPlayerController? player, CommandInfo command) player.localise("warden.remove_warden_command_desc"); player.localise("warden.laser_colour_command_desc"); player.localise("warden.marker_colour_command_desc"); + player.localise("warden.wsd_command_desc"); + player.localise("warden.wsd_ff_command_desc"); } public void take_warden_cmd(CCSPlayerController? player, CommandInfo command) @@ -368,9 +373,13 @@ void setup_cvar() { Server.ExecuteCommand("mp_force_pick_time 3000"); Server.ExecuteCommand("mp_autoteambalance 0"); - Server.ExecuteCommand("mp_equipment_reset_rounds 1"); - Server.ExecuteCommand("mp_t_default_secondary \"\" "); - Server.ExecuteCommand("mp_ct_default_secondary \"\" "); + + if(config.strip_spawn_weapons) + { + Server.ExecuteCommand("mp_equipment_reset_rounds 1"); + Server.ExecuteCommand("mp_t_default_secondary \"\" "); + Server.ExecuteCommand("mp_ct_default_secondary \"\" "); + } } public void round_start() @@ -457,15 +466,24 @@ public void setup_player_guns(CCSPlayerController? player) return; } - // cvars take care of this for us now - // player.strip_weapons(); + // strip weapons just in case + if(config.strip_spawn_weapons) + { + player.strip_weapons(); + } if(player.is_ct()) { if(config.ct_guns) { + var jail_player = jail_player_from_player(player); + player.GiveNamedItem("weapon_deagle"); - player.GiveNamedItem("weapon_m4a1"); + + if(jail_player != null) + { + player.GiveNamedItem(Lib.gun_give_name(jail_player.ct_gun)); + } } if(config.ct_armour) @@ -518,6 +536,22 @@ public void warden_death() remove_warden(); } + [RequiresPermissions("@css/generic")] + public void fire_guard_cmd(CCSPlayerController? invoke, CommandInfo command) + { + Lib.localise_announce(WARDEN_PREFIX,"warden.fire_guard"); + + // swap every guard apart from warden to T + List players = Utilities.GetPlayers(); + var valid = players.FindAll(player => player.is_valid() && player.is_ct() && !is_warden(player)); + + foreach(var player in valid) + { + player.slay(); + player.SwitchTeam(CsTeam.Terrorist); + } + } + public void death(CCSPlayerController? player, CCSPlayerController? killer) { // player is no longer on server @@ -558,8 +592,16 @@ public void ct_guns(CCSPlayerController player, ChatMenuOption option) player.strip_weapons(); + + var jail_player = jail_player_from_player(player); + + if(jail_player != null) + { + jail_player.update_player(player, "ct_gun", option.Text); + jail_player.ct_gun = option.Text; + } - player.GiveNamedItem("weapon_" + Lib.gun_give_name(option.Text)); + player.GiveNamedItem(Lib.gun_give_name(option.Text)); player.GiveNamedItem("weapon_deagle"); if(config.ct_armour) @@ -639,7 +681,7 @@ public void weapon_fire(CCSPlayerController? player, String name) public JailConfig config = new JailConfig(); - JailPlayer[] jail_players = new JailPlayer[64]; + public JailPlayer[] jail_players = new JailPlayer[64]; public Warday warday = new Warday(); public Block block = new Block();