diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a62381 --- /dev/null +++ b/.gitignore @@ -0,0 +1,261 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +.vscode/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc diff --git a/AdminTools.sln b/AdminTools.sln new file mode 100644 index 0000000..794e1ee --- /dev/null +++ b/AdminTools.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdminTools", "AdminTools\AdminTools.csproj", "{560DA2C9-E7A1-42C5-BBD4-5B3C28591593}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {560DA2C9-E7A1-42C5-BBD4-5B3C28591593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {560DA2C9-E7A1-42C5-BBD4-5B3C28591593}.Debug|Any CPU.Build.0 = Debug|Any CPU + {560DA2C9-E7A1-42C5-BBD4-5B3C28591593}.Release|Any CPU.ActiveCfg = Release|Any CPU + {560DA2C9-E7A1-42C5-BBD4-5B3C28591593}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/AdminTools/AdminTools.csproj b/AdminTools/AdminTools.csproj new file mode 100644 index 0000000..8372222 --- /dev/null +++ b/AdminTools/AdminTools.csproj @@ -0,0 +1,77 @@ + + + + + Debug + AnyCPU + {560DA2C9-E7A1-42C5-BBD4-5B3C28591593} + Library + Properties + AdminTools + AdminTools + v4.7.2 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\References\Assembly-CSharp_publicized.dll + + + ..\..\References\Assembly-CSharp-firstpass.dll + + + ..\..\References\EXILED.dll + + + ..\..\References\EXILED_Events.dll + + + ..\..\References\Mirror.dll + + + + + + + ..\..\References\UnityEngine.dll + + + ..\..\References\UnityEngine.CoreModule.dll + + + + + + + + + + + + + diff --git a/AdminTools/EventHandlers.cs b/AdminTools/EventHandlers.cs new file mode 100644 index 0000000..2e680be --- /dev/null +++ b/AdminTools/EventHandlers.cs @@ -0,0 +1,725 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using EXILED; +using MEC; +using Mirror; +using UnityEngine; +using Utf8Json.Resolvers.Internal; + +namespace AdminTools +{ + public class EventHandlers + { + private readonly Plugin plugin; + public EventHandlers(Plugin plugin) => this.plugin = plugin; + + public void OnCommand(ref RACommandEvent ev) + { + if (ev.Command.Contains("REQUEST_DATA PLAYER_LIST SILENT")) + return; + + string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + string scpFolder = Path.Combine(appData, "SCP Secret Laboratory"); + string logs = Path.Combine(scpFolder, "AdminLogs"); + string fileName = Path.Combine(logs, $"command_log-{ServerConsole.Port}.txt"); + if (!Directory.Exists(logs)) + Directory.CreateDirectory(logs); + if (!File.Exists(fileName)) + File.Create(fileName).Close(); + string data = $"{DateTime.Now}: {ev.Sender.Nickname} ({ev.Sender.SenderId}) executed: {ev.Command} {Environment.NewLine}"; + File.AppendAllText(fileName, data); + + string[] args = ev.Command.Split(' '); + ReferenceHub sender = Plugin.GetPlayer(ev.Sender.SenderId); + + switch (args[0].ToLower()) + { + case "kick": + { + ev.Allow = false; + IEnumerable reasons = args.Where(s => s != args[0] && s != args[1]); + string reason = ""; + foreach (string st in reasons) + reason += st; + GameObject obj = Plugin.GetPlayer(args[1])?.gameObject; + if (obj == null) + { + ev.Sender.RAMessage("Player not found", false); + return; + } + ServerConsole.Disconnect(obj, $"You have been kicked from the server: {reason}"); + ev.Sender.RAMessage("Player was kicked."); + return; + } + case "muteall": + { + ev.Allow = false; + foreach (ReferenceHub hub in Plugin.GetHubs()) + if (!hub.serverRoles.RemoteAdmin) + hub.characterClassManager.SetMuted(true); + ev.Sender.RAMessage("All non-staff players have been muted."); + return; + } + case "unmuteall": + { + ev.Allow = false; + foreach (ReferenceHub hub in Plugin.GetHubs()) + if (!hub.serverRoles.RemoteAdmin) + hub.characterClassManager.SetMuted(false); + ev.Sender.RAMessage("All non-staff players have been muted."); + return; + } + case "rocket": + { + ev.Allow = false; + ReferenceHub hub = Plugin.GetPlayer(args[1]); + if (hub == null && args[1] != "*" && args[1] != "all") + { + ev.Sender.RAMessage("Player not found."); + return; + } + + if (!float.TryParse(args[2], out float result)) + { + ev.Sender.RAMessage($"Speed argument invalid: {args[2]}"); + return; + } + + if (args[1] == "*" || args[1] == "all") + foreach (ReferenceHub h in Plugin.GetHubs()) + Timing.RunCoroutine(DoRocket(h, result)); + else + Timing.RunCoroutine(DoRocket(hub, result)); + ev.Sender.RAMessage("We're going on a trip, in our favorite rocketship."); + return; + } + case "bc": + { + ev.Allow = false; + IEnumerable thing = args.Skip(2); + string msg = ""; + foreach (string s in thing) + msg += $"{s} "; + uint time = uint.Parse(args[1]); + foreach (GameObject p in PlayerManager.players) + p.GetComponent() + .TargetAddElement(p.GetComponent().connectionToClient, msg, time, + false); + ev.Sender.RAMessage("Broadcast Sent."); + break; + } + case "id": + { + ev.Allow = false; + string id; + ReferenceHub rh = Plugin.GetPlayer(args[1]); + + id = rh == null ? "Player not found" : rh.characterClassManager.UserId; + ev.Sender.RAMessage($"{rh.nicknameSync.MyNick} - {id}"); + break; + } + case "pbc": + { + ev.Allow = false; + if (args.Length < 4) + { + ev.Sender.RAMessage( + "You must provide a players name/id, a number in seconds to display the broadcast, and a message", + false); + break; + } + + if (!uint.TryParse(args[2], out uint result)) + { + ev.Sender.RAMessage("You must provide a valid integer for a duration.", false); + break; + } + + IEnumerable thing = args.Skip(3); + string msg = ""; + foreach (string s in thing) + msg += $"{s} "; + Plugin.GetPlayer(args[1])?.Broadcast(result, msg); + ev.Sender.RAMessage("Message sent."); + break; + } + case "tut": + { + ev.Allow = false; + + if (args.Length < 2) + { + ev.Sender.RAMessage("You must supply a player name or ID", false); + return; + } + + ReferenceHub rh = Plugin.GetPlayer(string.Join(" ", args.Skip(1))); + if (rh == null) + { + ev.Sender.RAMessage("Player not found.", false); + return; + } + + if (rh.characterClassManager.CurClass != RoleType.Tutorial) + { + Timing.RunCoroutine(DoTut(rh)); + ev.Sender.RAMessage("Player set as tutorial."); + } + else + { + ev.Sender.RAMessage("Player unset as Tutorial (killed)."); + rh.characterClassManager.SetPlayersClass(RoleType.Spectator, rh.gameObject); + } + + break; + } + case "hidetags": + ev.Allow = false; + foreach (ReferenceHub hub in Plugin.GetHubs()) + if (hub.serverRoles.RemoteAdmin) + { + hub.serverRoles.HiddenBadge = hub.serverRoles.MyText; + hub.serverRoles.NetworkGlobalBadge = null; + hub.serverRoles.SetText(null); + hub.serverRoles.SetColor(null); + hub.serverRoles.GlobalSet = false; + hub.serverRoles.RefreshHiddenTag(); + } + + ev.Sender.RAMessage("All staff tags hidden."); + + break; + case "showtags": + ev.Allow = false; + foreach (ReferenceHub hub in Plugin.GetHubs()) + if (hub.serverRoles.RemoteAdmin && !hub.serverRoles.RaEverywhere) + { + hub.serverRoles.HiddenBadge = null; + hub.serverRoles.RpcResetFixed(); + hub.serverRoles.RefreshPermissions(true); + } + + ev.Sender.RAMessage("All staff tags shown."); + + break; + case "jail": + { + ev.Allow = false; + if (args.Length < 2) + { + ev.Sender.RaReply("Joker's Plugin#You must supply a player name or ID", false, true, string.Empty); + return; + } + + var array = args.Where(a => a != args[0]); + string filter = null; + foreach (string s in array) + filter += s; + ReferenceHub target = Plugin.GetPlayer(filter); + if (target == null) + ev.Sender.RaReply("Joker's Plugin#User not found.", false, true, string.Empty); + if (plugin.JailedPlayers.Any(j => j.Userid == target.characterClassManager.UserId)) + { + Timing.RunCoroutine(DoUnJail(target)); + ev.Sender.RaReply("Joker's Plugin#User unjailed.", true, true, string.Empty); + } + else + { + Timing.RunCoroutine(DoJail(target)); + ev.Sender.RaReply("Joker's Plugin#User jailed.", true, true, string.Empty); + } + + break; + } + case "abc": + { + ev.Allow = false; + if (args.Length < 3) + { + ev.Sender.RAMessage("You must include a duration and a message.", false); + return; + } + + if (!uint.TryParse(args[1], out uint result)) + { + ev.Sender.RAMessage("You must provide a valid integer for a duration.", false); + break; + } + + IEnumerable thing2 = args.Skip(2); + string msg = ""; + foreach (string s in thing2) + msg += $"{s} "; + foreach (GameObject o in PlayerManager.players) + { + ReferenceHub rh = o.GetComponent(); + if (rh.serverRoles.RemoteAdmin) + rh.Broadcast(result, $"{ev.Sender.Nickname}: {msg}"); + } + + ev.Sender.RAMessage("Message sent to all online staff members."); + + break; + } + case "drop": + { + ev.Allow = false; + int result; + if (args.Length != 4) + { + ev.Sender.RAMessage($"Invalid arguments.{args.Length}"); + break; + } + + ReferenceHub hub = Plugin.GetPlayer(args[1]); + if (hub == null) + { + ev.Sender.RAMessage("Player not found."); + break; + } + + ItemType type = GetItemFromId(args[2]); + + if (!int.TryParse(args[3], out result)) + { + ev.Sender.RAMessage("Not a number doufus."); + break; + } + + if (result > 200) + { + ev.Sender.RAMessage("Try a lower number that won't crash my servers, ty."); + return; + } + + for (int i = 0; i < result; i++) + SpawnItem(type, hub.gameObject.transform.position, Vector3.zero); + ev.Sender.RAMessage("Done. hehexd"); + return; + } + case "pos": + { + ev.Allow = false; + + if (args.Length < 3) + { + ev.Sender.RAMessage("You must supply a player name/ID and a subcommand.", false); + return; + } + + ReferenceHub rh = Plugin.GetPlayer(args[1]); + if (rh == null) + { + ev.Sender.RAMessage("Player not found.", false); + return; + } + + switch (args[2].ToLower()) + { + case "set": + { + if (args.Length < 6) + { + ev.Sender.RAMessage("You must supply x, y and z coordinated.", false); + return; + } + + if (!float.TryParse(args[3], out float x)) + { + ev.Sender.RAMessage("Invalid x coordinates."); + return; + } + + if (!float.TryParse(args[4], out float y)) + { + ev.Sender.RAMessage("Invalid y coordinates."); + return; + } + + if (!float.TryParse(args[5], out float z)) + { + ev.Sender.RAMessage("Invalid z coordinates."); + return; + } + rh.plyMovementSync.OverridePosition(new Vector3(x, y, z), 0f, false ); + ev.Sender.RAMessage($"Player {rh.nicknameSync.MyNick} - {rh.characterClassManager.UserId} moved to x{x} y{y} z{z}"); + break; + } + case "get": + { + Vector3 pos = rh.gameObject.transform.position; + string ret = $"{rh.nicknameSync.MyNick} - {rh.characterClassManager.UserId} Position: x {pos.x} y {pos.y} z {pos.z}"; + ev.Sender.RAMessage(ret); + break; + } + case "add": + { + if (args[3] != "x" && args[3] != "y" && args[3] != "z") + { + ev.Sender.RAMessage("Invalid coordinate plane selected."); + return; + } + if (!float.TryParse(args[4], out float newPos)) + { + ev.Sender.RAMessage("Invalid coordinate."); + return; + } + + Vector3 pos = rh.plyMovementSync.RealModelPosition; + switch (args[3].ToLower()) + { + case "x": + rh.plyMovementSync.OverridePosition(new Vector3(pos.x + newPos, pos.y, pos.z), 0f); + break; + case "y": + rh.plyMovementSync.OverridePosition(new Vector3(pos.x, pos.y + newPos, pos.z), 0f); + break; + case "z": + rh.plyMovementSync.OverridePosition(new Vector3(pos.x, pos.y, pos.z + newPos), 0f); + break; + } + ev.Sender.RAMessage($"Player {rh.nicknameSync.MyNick} - {rh.characterClassManager.UserId} position changed."); + break; + } + } + + break; + } + case "tpx": + { + ev.Allow = false; + + if (args.Length < 3) + { + ev.Sender.RAMessage("You must supply a player name/ID to teleport and a player name/ID to teleport them to."); + return; + } + + ReferenceHub rh = Plugin.GetPlayer(args[1]); + ReferenceHub target = Plugin.GetPlayer(args[2]); + if (rh == null) + { + ev.Sender.RAMessage($"Player {args[1]} not found."); + return; + } + + if (target == null) + { + ev.Sender.RAMessage($"Player {args[2]} not found."); + return; + } + rh.plyMovementSync.OverridePosition(target.plyMovementSync.RealModelPosition, 0f, false); + ev.Sender.RAMessage($"{rh.nicknameSync.MyNick} teleported to {target.nicknameSync.MyNick}"); + break; + } + case "ghost": + { + ev.Allow = false; + if (args.Length < 2) + { + ev.Sender.RAMessage("You must supply a playername to ghost.", false); + return; + } + + ReferenceHub rh = Plugin.GetPlayer(args[1]); + if (rh == null) + { + ev.Sender.RAMessage("Player not found.", false); + return; + } + + if (EventPlugin.GhostedIds.Contains(rh.queryProcessor.PlayerId)) + { + EventPlugin.GhostedIds.Remove(rh.queryProcessor.PlayerId); + ev.Sender.RAMessage($"{rh.nicknameSync.MyNick} removed from ghostmode."); + return; + } + + EventPlugin.GhostedIds.Add(rh.queryProcessor.PlayerId); + ev.Sender.RAMessage($"{rh.nicknameSync.MyNick} ghosted."); + return; + } + case "restart": + { + ev.Allow = false; + if (ev.Sender.Nickname != "BLART" || ev.Sender.SenderId != "BLART") + { + ev.Sender.RAMessage("Permission denied."); + return; + } + ev.Sender.RAMessage("Restarting server forcefully..."); + foreach (PlayerStats stats in UnityEngine.Object.FindObjectsOfType()) + stats.CallRpcRoundrestart(0f); + Application.Quit(); + return; + } + case "scale": + { + ev.Allow = false; + if (args.Length < 3) + { + ev.Sender.RAMessage("You must provide a target and scale size."); + return; + } + + if (!float.TryParse(args[2], out float scale)) + { + ev.Sender.RAMessage("Invalid scale size selected."); + return; + } + + ReferenceHub rh = Plugin.GetPlayer(args[1]); + if (rh == null) + { + ev.Sender.RAMessage("Player not found."); + return; + } + + SetPlayerScale(rh.gameObject, scale); + ev.Sender.RAMessage($"{rh.nicknameSync.MyNick} size set to {scale}"); + return; + } + } + } + + public void SpawnItem(ItemType type, Vector3 pos, Vector3 rot) + { + PlayerManager.localPlayer.GetComponent().SetPickup(type, -4.656647E+11f, pos, Quaternion.Euler(rot), 0, 0, 0); + } + + private IEnumerator DoTut(ReferenceHub rh) + { + rh.characterClassManager.SetPlayersClass(RoleType.Tutorial, rh.gameObject, true); + yield return Timing.WaitForSeconds(1f); + var d = UnityEngine.Object.FindObjectsOfType(); + foreach (Door door in d) + if (door.DoorName == "SURFACE_GATE") + rh.plyMovementSync.OverridePosition(door.transform.position + Vector3.up * 2, 0f); + rh.serverRoles.CallTargetSetNoclipReady(rh.characterClassManager.connectionToClient, true); + rh.serverRoles.NoclipReady = true; + } + + public ItemType GetItemFromId(string id) + { + switch (id.ToUpper()) + { + case "018": + case "BALL": + return ItemType.SCP018; + case "05": + return ItemType.KeycardO5; + case "AMMO1": + return ItemType.Ammo556; + case "AMMO2": + return ItemType.Ammo762; + case "AMMO3": + return ItemType.Ammo9mm; + case "CENGINEER": + return ItemType.KeycardContainmentEngineer; + case "CHAOS_INSURGENCY": + return ItemType.KeycardChaosInsurgency; + case "CI": + return ItemType.KeycardChaosInsurgency; + case "COIN": + return ItemType.Coin; + case "COM15": + return ItemType.GunCOM15; + case "CONTAINMENT_ENGINEER": + return ItemType.KeycardContainmentEngineer; + case "DISARMER": + return ItemType.Disarmer; + case "E11": + return ItemType.GunE11SR; + case "E11_AMMO": + return ItemType.Ammo556; + case "E11_STANDARD_RIFLE": + return ItemType.GunE11SR; + case "EAMMO": + return ItemType.Ammo556; + case "EPSILON": + return ItemType.GunE11SR; + case "EPSILON11": + return ItemType.GunE11SR; + case "EPSILON11_STANDARD_RIFLE": + return ItemType.GunE11SR; + case "EPSILON_RIFLE": + return ItemType.GunE11SR; + case "EPSILON_STANDARD_RIFLE": + return ItemType.GunE11SR; + case "E_AMMO": + return ItemType.Ammo556; + case "FACILITY_MANAGER": + return ItemType.KeycardFacilityManager; + case "FLASH": + return ItemType.GrenadeFlash; + case "FLASHBANG": + return ItemType.GrenadeFlash; + case "FLASHLIGHT": + return ItemType.Flashlight; + case "FMANAGER": + return ItemType.KeycardFacilityManager; + case "FRAG": + return ItemType.GrenadeFrag; + case "FRAG_GRENADE": + return ItemType.GrenadeFrag; + case "GRENADE": + return ItemType.GrenadeFrag; + case "GUARD": + return ItemType.KeycardGuard; + case "JANITOR": + return ItemType.KeycardJanitor; + case "LOGICER": + return ItemType.GunLogicer; + case "LOGICIZER": + return ItemType.GunLogicer; + case "MAJOR_SCIENTIST": + return ItemType.KeycardScientistMajor; + case "MEDKIT": + return ItemType.Medkit; + case "MICRO": + return ItemType.MicroHID; + case "MICROHID": + return ItemType.MicroHID; + case "MP4": + return ItemType.GunMP7; + case "MP7": + return ItemType.GunMP7; + case "MSCIENTIST": + return ItemType.KeycardScientistMajor; + case "MTFC": + return ItemType.KeycardNTFCommander; + case "MTFL": + return ItemType.KeycardNTFLieutenant; + case "MTF_COMMANDER": + return ItemType.KeycardNTFCommander; + case "MTF_LIEUTENANT": + return ItemType.KeycardNTFLieutenant; + case "O5": + return ItemType.KeycardO5; + case "O5_LEVEL": + return ItemType.KeycardO5; + case "P90": + return ItemType.GunProject90; + case "PISTOL": + return ItemType.GunCOM15; + case "PROJECT_90": + return ItemType.GunProject90; + case "RADIO": + return ItemType.Radio; + case "RIFLE": + return ItemType.GunE11SR; + case "SCIENTIST": + return ItemType.KeycardScientist; + case "SENIOR_GUARD": + return ItemType.KeycardSeniorGuard; + case "SGUARD": + return ItemType.KeycardSeniorGuard; + case "WEAPON_MANAGER": + return ItemType.WeaponManagerTablet; + case "WEAPON_MANAGER_TABLET": + return ItemType.WeaponManagerTablet; + case "WMT": + return ItemType.WeaponManagerTablet; + case "ZMANAGER": + return ItemType.KeycardZoneManager; + case "ZONE_MANAGER": + return ItemType.KeycardZoneManager; + default: + return ItemType.Coin; + } + } + + public void SetPlayerScale(GameObject target, float scale) + { + try + { + NetworkIdentity identity = target.GetComponent(); + + + target.transform.localScale *= scale; + + ObjectDestroyMessage destroyMessage = new ObjectDestroyMessage(); + destroyMessage.netId = identity.netId; + + + foreach (GameObject player in PlayerManager.players) + { + if (player == target) + continue; + + NetworkConnection playerCon = player.GetComponent().connectionToClient; + + playerCon.Send(destroyMessage, 0); + + object[] parameters = new object[] {identity, playerCon}; + typeof(NetworkServer).InvokeStaticMethod("SendSpawnMessage", parameters); + } + } + catch (Exception e) + { + Plugin.Info($"Set Scale error: {e}"); + } + } + + public IEnumerator DoRocket(ReferenceHub hub, float speed) + { + const int maxAmnt = 50; + int amnt = 0; + while (hub.characterClassManager.CurClass != RoleType.Spectator) + { + hub.plyMovementSync.OverridePosition(hub.gameObject.transform.position + Vector3.up * speed, 0f, false); + amnt++; + if (amnt >= maxAmnt) + { + hub.characterClassManager.GodMode = false; + hub.playerStats.HurtPlayer(new PlayerStats.HitInfo(1000000, "WORLD", DamageTypes.Grenade, 0), + hub.gameObject); + } + + yield return Timing.WaitForOneFrame; + } + } + + public IEnumerator DoJail(ReferenceHub rh, bool skipadd = false) + { + List items = new List(); + foreach (var item in rh.inventory.items) + items.Add(item.id); + if (!skipadd) + plugin.JailedPlayers.Add(new Jailed + { + Health = rh.playerStats.health, + Position = rh.gameObject.transform.position, + Items = items, + Name = rh.characterClassManager.name, + Role = rh.characterClassManager.CurClass, + Userid = rh.characterClassManager.UserId, + }); + yield return Timing.WaitForSeconds(1f); + rh.characterClassManager.SetClassID(RoleType.Tutorial); + rh.gameObject.transform.position = new Vector3(53f, 1020f, -44f); + rh.inventory.items.Clear(); + } + + private IEnumerator DoUnJail(ReferenceHub rh) + { + var jail = plugin.JailedPlayers.Find(j => j.Userid == rh.characterClassManager.UserId); + rh.characterClassManager.SetClassID(jail.Role); + foreach (ItemType item in jail.Items) + rh.inventory.AddNewItem(item); + yield return Timing.WaitForSeconds(1.5f); + rh.playerStats.health = jail.Health; + rh.plyMovementSync.OverridePosition(jail.Position, 0f); + rh.gameObject.transform.position = jail.Position; + plugin.JailedPlayers.Remove(jail); + } + + public void OnPlayerJoin(PlayerJoinEvent ev) + { + if (plugin.JailedPlayers.Any(j => j.Userid == ev.Player.characterClassManager.UserId)) + Timing.RunCoroutine(DoJail(ev.Player, true)); + } + } +} \ No newline at end of file diff --git a/AdminTools/Extensions.cs b/AdminTools/Extensions.cs new file mode 100644 index 0000000..b18220d --- /dev/null +++ b/AdminTools/Extensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Reflection; + +namespace AdminTools +{ + public static class Extensions + { + public static void RAMessage(this CommandSender sender, string message, bool success = true) => + sender.RaReply("AdminTools#" + message, success, true, string.Empty); + + public static void InvokeStaticMethod(this Type type, string methodName, object[] param) + { + BindingFlags flags = BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic | + BindingFlags.Static | BindingFlags.Public; + MethodInfo info = type.GetMethod(methodName, flags); + info?.Invoke(null, param); + } + + public static void Broadcast(this ReferenceHub rh, uint time, string message) => + rh.GetComponent() + .TargetAddElement(rh.scp079PlayerScript.connectionToClient, message, time, false); + } +} \ No newline at end of file diff --git a/AdminTools/Jailed.cs b/AdminTools/Jailed.cs new file mode 100644 index 0000000..91b7287 --- /dev/null +++ b/AdminTools/Jailed.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace AdminTools +{ + public class Jailed + { + public string Userid; + public string Name; + public List Items; + public RoleType Role; + public Vector3 Position; + public float Health; + } +} \ No newline at end of file diff --git a/AdminTools/Plugin.cs b/AdminTools/Plugin.cs new file mode 100644 index 0000000..70285c2 --- /dev/null +++ b/AdminTools/Plugin.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using EXILED; + +namespace AdminTools +{ + public class Plugin : EXILED.Plugin + { + public EventHandlers EventHandlers; + public List JailedPlayers = new List(); + + public override void OnEnable() + { + EventHandlers = new EventHandlers(this); + Events.RemoteAdminCommandEvent += EventHandlers.OnCommand; + Events.PlayerJoinEvent += EventHandlers.OnPlayerJoin; + } + + public override void OnDisable() + { + + } + + public override void OnReload() + { + + } + + public override string getName { get; } = "AdminTools"; + } +} \ No newline at end of file diff --git a/AdminTools/Properties/AssemblyInfo.cs b/AdminTools/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e62d2fa --- /dev/null +++ b/AdminTools/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AdminTools")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AdminTools")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("560DA2C9-E7A1-42C5-BBD4-5B3C28591593")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file