├── .gitattributes
├── .gitignore
├── CHANGELOG.md
├── CedMod-SampleEvent-NWApi
├── App.config
├── CedMod-SampleEvent-NWApi.csproj
├── Config.cs
├── EventHandler.cs
├── Properties
│ └── AssemblyInfo.cs
├── SampleEvent.cs
└── packages.config
├── CedMod.sln
├── CedMod
├── API.cs
├── Addons
│ ├── AdminSitSystem
│ │ ├── AdminSit.cs
│ │ ├── AdminSitHandler.cs
│ │ ├── AdminSitLocation.cs
│ │ └── Commands
│ │ │ ├── Jail
│ │ │ ├── Add.cs
│ │ │ ├── Create.cs
│ │ │ ├── Delete.cs
│ │ │ ├── Join.cs
│ │ │ └── Remove.cs
│ │ │ └── JailCommand.cs
│ ├── Audio
│ │ ├── AudioCommand.cs
│ │ ├── CustomAudioPlayer.cs
│ │ └── FakeConnection.cs
│ ├── Events
│ │ ├── Commands
│ │ │ ├── BumpEvent.cs
│ │ │ ├── DisableEvent.cs
│ │ │ ├── EnableEvent.cs
│ │ │ ├── Events.cs
│ │ │ ├── ListEvents.cs
│ │ │ ├── PopuplateCommand.cs
│ │ │ └── Queue.cs
│ │ ├── Config.cs
│ │ ├── EventManager.cs
│ │ ├── EventManagerPlayerEvents.cs
│ │ ├── EventManagerServerEvents.cs
│ │ ├── HintManager.cs
│ │ ├── IEventConfig.cs
│ │ ├── Interfaces
│ │ │ ├── IBulletHoleBehaviour.cs
│ │ │ ├── IEndConditionBehaviour.cs
│ │ │ ├── IEvent.cs
│ │ │ ├── IFriendlyFireAutoBanBehaviour.cs
│ │ │ └── IMapgenBehaviour.cs
│ │ ├── Patches
│ │ │ ├── BulletHolePatch.cs
│ │ │ └── SeedGenerationPatch.cs
│ │ └── ScriptedEventIntergration.cs
│ ├── QuerySystem
│ │ ├── Commands
│ │ │ ├── CmSyncCommand.cs
│ │ │ ├── ImportRaCommand.cs
│ │ │ ├── NearbyBulletHoles.cs
│ │ │ ├── RestartQuery.cs
│ │ │ └── ToggleExpTracking.cs
│ │ ├── Config.cs
│ │ ├── Extensions.cs
│ │ ├── LevelerStore.cs
│ │ ├── Patches
│ │ │ ├── BulletHolePatch.cs
│ │ │ ├── CommandProcessorPatch.cs
│ │ │ ├── ExiledPermissionsPatch.cs
│ │ │ ├── ExiledPermissionsPatchPlayer.cs
│ │ │ ├── PreAuthModel.cs
│ │ │ ├── RefreshExiledPermissions.cs
│ │ │ ├── RefreshPermissionsHandlerPatch.cs
│ │ │ ├── ReservedSlotsPatch.cs
│ │ │ └── ShootingPatch.cs
│ │ ├── PlayerList.cs
│ │ ├── QueryMapEvents.cs
│ │ ├── QueryPlayerEvents.cs
│ │ ├── QueryServerEvents.cs
│ │ ├── QuerySystem.cs
│ │ ├── ServerPreferences.cs
│ │ ├── ThreadDispatcher.cs
│ │ ├── Verification.cs
│ │ └── WS
│ │ │ ├── PermissionProvider.cs
│ │ │ └── WebSocketSystem.cs
│ ├── Sentinal
│ │ ├── Patches
│ │ │ ├── FpcServerPositionDistributorPatch.cs
│ │ │ ├── FpcSyncDataPatch.cs
│ │ │ ├── ItemPickupHandler.cs
│ │ │ ├── PlayerRoleManagerPatch.cs
│ │ │ ├── Scp939LungePatch.cs
│ │ │ ├── TeslaGateHandler.cs
│ │ │ ├── Utilities
│ │ │ │ └── RoomCache.cs
│ │ │ └── VoicePacketPacket.cs
│ │ └── SentinalBehaviour.cs
│ └── StaffInfo
│ │ ├── MirrorExtensions.cs
│ │ └── StaffInfoHandler.cs
├── ApiModals
│ ├── AudioHeartBeat.cs
│ ├── AutoSlPermsSlRequest.cs
│ ├── CedModVersion.cs
│ ├── EventModal.cs
│ ├── ExiledVersion.cs
│ ├── HeartbeatRequest.cs
│ ├── HelloMessage.cs
│ ├── IngameUserPreferences.cs
│ ├── PlayerObject.cs
│ ├── SCPSLVersion.cs
│ └── ServerPreferenceModel.cs
├── App.config
├── BanSystem.cs
├── CacheHandler.cs
├── CedMod-Main.csproj
├── CedModConfig.cs
├── CedModPlayer.cs
├── Commands
│ ├── CedModSetupCommand.cs
│ ├── CheckForUpdatesCommand.cs
│ ├── Dialog
│ │ ├── all.cs
│ │ └── userid.cs
│ ├── DialogBox.cs
│ ├── FFADisable.cs
│ ├── InstallUpdateCommand.cs
│ ├── LightColor.cs
│ ├── RainbowLights.cs
│ ├── Redirect.cs
│ └── WarnCommand.cs
├── Components
│ ├── AutoUpdater.cs
│ └── RemoteAdminModificationHandler.cs
├── Config.cs
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── FriendlyFireAutoban.cs
├── Handlers
│ ├── Player.cs
│ └── Server.cs
├── Patches
│ ├── BanCommandPatch.cs
│ ├── BanPatch.cs
│ ├── ExternalLookupPatch.cs
│ ├── IntercomMuteCommandPatch.cs
│ ├── IntercomUnMuteCommandPatch.cs
│ ├── IssueBanPatch.cs
│ ├── MirrorPatch.cs
│ ├── MuteCommandPatch.cs
│ ├── NpcInstanceModePatch.cs
│ ├── OBanCommandPatch.cs
│ ├── RAProcessPlayerPatch.cs
│ ├── RaPlayerAuthPatch.cs
│ ├── RaPlayerListPatch.cs
│ ├── RaPlayerPatch.cs
│ ├── ReloadServerNamePatch.cs
│ └── UnMuteCommandPatch.cs
├── Plugin.cs
├── Properties
│ └── AssemblyInfo.cs
├── README.md
├── RainbowLight.cs
├── VerificationChallenge.cs
├── packages.config
├── version.txt
└── versionIdentifier.txt
├── README.md
└── SECURITY.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | V: 3.4.25
3 | - Introduced CMAC officially.
4 | - Prevents Harmless Tesla cheats (negates tesla damage)1*
5 | - Prevents pickup through walls cheats1*
6 | - Prevents Movement Unlock cheats (allows movement where the game would normally lock your movement)1*
7 | - Introduced a system to prevent wallhacks.2*
8 | - Improved communication to Sentinal3*
9 | - Fixed OnPlayerDying log on the panel when there was no killer.
10 | - Fixed the jail command spawning you up in the air if unjailed after warhead detonation.
11 |
12 | 1* Detection results will be shared with the CedMod gateway to create a cheat profile on the user, which will be used to determine if the user is cheating based on the currently implemented detections
13 | If enough detections are triggered the user will be banned based on their account standing (lower/newer standing means faster action)
14 | These features have been tested and adapted for users with higher than usual or unstable connections as best as possible
15 | We continue to monitor results detection logs and making changes where necessary.
16 | Please note that effectiveness is dependent on how many cheaters use the detected features until we add detections for more features with 3*
17 |
18 | 2* This system will hide players from others when they cannot actually see them with a series of checks to make it effective yet unnoticeable for normal players
Please note that this currently does not apply to SCP's
Please also note that actions that make sound can also reveal players to others despite not having a LineOfSight
19 |
20 | 3* Sentinal is the WIP completely CedMod-server-side simulation system which is capable of reconstructing the entire round out side of SL.
21 | In the future it will be used to detect more sophisticated cheat features, eg aimbot, pSilent, etc. while completely hiding the detection code.
--------------------------------------------------------------------------------
/CedMod-SampleEvent-NWApi/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/CedMod-SampleEvent-NWApi/Config.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using CedMod.Addons.Events;
3 |
4 | namespace CedMod.SampleEvent
5 | {
6 | public sealed class Config: IEventConfig
7 | {
8 | [Description("Indicates whether the event is enabled or not")]
9 | public bool IsEnabled { get; set; } = true;
10 | }
11 | }
--------------------------------------------------------------------------------
/CedMod-SampleEvent-NWApi/EventHandler.cs:
--------------------------------------------------------------------------------
1 | using PlayerStatsSystem;
2 | using PluginAPI.Core.Attributes;
3 | using PluginAPI.Enums;
4 | using PluginAPI.Events;
5 |
6 | namespace CedMod.SampleEvent
7 | {
8 | public class EventHandler
9 | {
10 |
11 | [PluginEvent(ServerEventType.PlayerDeath)]
12 | public void OnPlayerDeath(PlayerDeathEvent ev)
13 | {
14 | ev.Player.SendBroadcast("You died!", 1, Broadcast.BroadcastFlags.Normal);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/CedMod-SampleEvent-NWApi/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("CedMod_SampleEvent")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("CedMod_SampleEvent")]
12 | [assembly: AssemblyCopyright("Copyright © 2021")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("2F1B2CB5-0B6B-44DB-9FA4-CB357420C36D")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/CedMod-SampleEvent-NWApi/SampleEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CedMod.Addons.Events;
3 | using CedMod.Addons.Events.Interfaces;
4 | using HarmonyLib;
5 | using LabApi.Features.Console;
6 | using LabApi.Loader.Features.Plugins;
7 | using PluginAPI.Core;
8 | using PluginAPI.Core.Attributes;
9 | using UnityEngine.XR;
10 | using EventManager = PluginAPI.Events.EventManager;
11 |
12 | namespace CedMod.SampleEvent
13 | {
14 | public class SampleEvent : Plugin, IEvent
15 | {
16 | public static bool IsRunning = false;
17 |
18 | [PluginUnload]
19 | public void OnDisabled()
20 | {
21 | StopEvent();
22 | }
23 |
24 | public string EventName { get; } = "Example Event";
25 | public string EvenAuthor { get; } = "ced777ric";
26 | public string EventDescription { get; set; } = "A testing event, you can use this to make your own events";
27 | public string EventPrefix { get; } = "Sample";
28 |
29 | public IEventConfig EventConfig => Config;
30 |
31 | public void PrepareEvent()
32 | {
33 | Logger.Info("SampleEvent is preparing");
34 | IsRunning = true;
35 | Logger.Info("SampleEvent is prepared");
36 | EventManager.RegisterEvents(this);
37 | }
38 |
39 | public void StopEvent()
40 | {
41 | IsRunning = false;
42 | EventManager.UnregisterEvents(this);
43 | }
44 |
45 | public override void Enable()
46 | {
47 | throw new NotImplementedException();
48 | }
49 |
50 | public override void Disable()
51 | {
52 | throw new NotImplementedException();
53 | }
54 |
55 | public override string Name { get; }
56 | public override string Description { get; }
57 | public override string Author { get; }
58 | public override Version Version { get; }
59 | public override Version RequiredApiVersion { get; }
60 | }
61 | }
--------------------------------------------------------------------------------
/CedMod-SampleEvent-NWApi/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/CedMod.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 15
3 | VisualStudioVersion = 15.0.28307.645
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CedMod-Main", "CedMod\CedMod-Main.csproj", "{B404BA59-5C33-41DC-8FEE-0F10F087089D}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CedMod-SampleEvent-NWApi", "CedMod-SampleEvent-NWApi\CedMod-SampleEvent-NWApi.csproj", "{2F1B2CB5-0B6B-44DB-9FA4-CB357420C36D}"
8 | EndProject
9 | Global
10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
11 | Debug|Any CPU = Debug|Any CPU
12 | Release|Any CPU = Release|Any CPU
13 | Debug EXILED|Any CPU = Debug EXILED|Any CPU
14 | Release EXILED|Any CPU = Release EXILED|Any CPU
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Debug EXILED|Any CPU.ActiveCfg = Debug EXILED|Any CPU
22 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Debug EXILED|Any CPU.Build.0 = Debug EXILED|Any CPU
23 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Release EXILED|Any CPU.ActiveCfg = Release EXILED|Any CPU
24 | {B404BA59-5C33-41DC-8FEE-0F10F087089D}.Release EXILED|Any CPU.Build.0 = Release EXILED|Any CPU
25 | EndGlobalSection
26 | GlobalSection(SolutionProperties) = preSolution
27 | HideSolutionNode = FALSE
28 | EndGlobalSection
29 | GlobalSection(ExtensibilityGlobals) = postSolution
30 | SolutionGuid = {804FCAB2-81D5-4ABD-BD5A-384E4807240F}
31 | EndGlobalSection
32 | EndGlobal
33 |
--------------------------------------------------------------------------------
/CedMod/Addons/AdminSitSystem/AdminSit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using AdminToys;
4 | using InventorySystem.Items;
5 | using LabApi.Features.Wrappers;
6 | using PlayerRoles;
7 | using UnityEngine;
8 |
9 | namespace CedMod.Addons.AdminSitSystem
10 | {
11 | public class AdminSit
12 | {
13 | public string Id { get; set; } = Guid.NewGuid().ToString();
14 | public AdminSitLocation Location { get; set; }
15 | public AdminSitType Type { get; set; }
16 | public string InitialReason { get; set; }
17 | public long InitialDuration { get; set; }
18 | public int AssociatedReportId { get; set; }
19 | public List Players { get; set; }
20 | public List SpawnedObjects { get; set; }
21 | }
22 |
23 | public class AdminSitPlayer
24 | {
25 | public string UserId { get; set; }
26 | public Player Player { get; set; }
27 | public AdminSitPlayerType PlayerType { get; set; }
28 | public Dictionary Items { get; set; }
29 | public RoleTypeId Role { get; set; }
30 | public Vector3 Position { get; set; }
31 | public float Health { get; set; }
32 | public Dictionary Ammo { get; set; }
33 | public Dictionary> Effects = new Dictionary>();
34 | }
35 |
36 | public enum AdminSitPlayerType
37 | {
38 | Staff,
39 | Handler,
40 | Offender,
41 | Victim,
42 | User
43 | }
44 |
45 | public enum AdminSitType
46 | {
47 | Generic,
48 | Jail,
49 | BanOffenderOnLeave,
50 | }
51 | }
--------------------------------------------------------------------------------
/CedMod/Addons/AdminSitSystem/AdminSitLocation.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace CedMod.Addons.AdminSitSystem
4 | {
5 | public class AdminSitLocation
6 | {
7 | public Vector3 SpawnPosition { get; set; }
8 | public bool InUse { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/CedMod/Addons/AdminSitSystem/Commands/Jail/Add.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CommandSystem;
4 | using LabApi.Features.Permissions;
5 |
6 | namespace CedMod.Addons.AdminSitSystem.Commands.Jail
7 | {
8 | public class Add : ICommand
9 | {
10 | public string Command { get; } = "add";
11 |
12 | public string[] Aliases { get; } = {
13 | "a"
14 | };
15 |
16 | public string Description { get; } = "Adds the specified player to your current jail.";
17 |
18 | public bool Execute(ArraySegment arguments, ICommandSender sender,
19 | out string response)
20 | {
21 | if (!sender.HasPermissions("cedmod.jail"))
22 | {
23 | response = "no permission";
24 | return false;
25 | }
26 |
27 | if (arguments.Count < 1)
28 | {
29 | response = "This command requires a PlayerId to be specified";
30 | return false;
31 | }
32 |
33 | var invoker = CedModPlayer.Get((sender as CommandSender).SenderId);
34 | if (!AdminSitHandler.Singleton.Sits.Any(s => s.Players.Any(s => s.UserId == invoker.UserId)))
35 | {
36 | response = "You are currently not part of any jail.";
37 | return false;
38 | }
39 |
40 | if (invoker == null)
41 | {
42 | response = $"Invoker could not be found.";
43 | return false;
44 | }
45 |
46 | var sit = AdminSitHandler.Singleton.Sits.FirstOrDefault(s => s.Players.Any(s => s.UserId == invoker.UserId));
47 |
48 | var plr = CedModPlayer.Get(arguments.At(0));
49 | if (plr is null)
50 | {
51 | response = $"Player '{arguments.At(0)}' could not be found";
52 | return false;
53 | }
54 | if (AdminSitHandler.Singleton.Sits.Any(s => s.Players.Any(s => s.UserId == plr.UserId)))
55 | {
56 | response = "The specified player is already part of a jail.";
57 | return false;
58 | }
59 |
60 | JailParentCommand.AddPlr(plr, sit);
61 |
62 | response = "Player Added, use jail remove {playerId} to remove the player.";
63 | return false;
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/CedMod/Addons/AdminSitSystem/Commands/Jail/Create.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using AdminToys;
5 | using CommandSystem;
6 | using LabApi.Features.Permissions;
7 | using LabApi.Features.Wrappers;
8 | using Mirror;
9 | using UnityEngine;
10 |
11 | namespace CedMod.Addons.AdminSitSystem.Commands.Jail
12 | {
13 | public class Create : ICommand
14 | {
15 | public string Command { get; } = "create";
16 |
17 | public string[] Aliases { get; } = {
18 | "cr",
19 | "c"
20 | };
21 |
22 | public string Description { get; } = "Assigns an available jail location to your player.";
23 |
24 | public bool Execute(ArraySegment arguments, ICommandSender sender,
25 | out string response)
26 | {
27 | if (!sender.HasPermissions("cedmod.jail"))
28 | {
29 | response = "no permission";
30 | return false;
31 | }
32 |
33 | if (!AdminSitHandler.Singleton.AdminSitLocations.Any(s => !s.InUse))
34 | {
35 | response = "There are no locations available.";
36 | return false;
37 | }
38 |
39 | var loc = AdminSitHandler.Singleton.AdminSitLocations.FirstOrDefault(s => !s.InUse);
40 | var plr = CedModPlayer.Get((sender as CommandSender).SenderId);
41 | if (plr == null)
42 | {
43 | response = $"Invoker could not be found.";
44 | return false;
45 | }
46 |
47 | if (AdminSitHandler.Singleton.Sits.Any(s => s.Players.Any(s => s.UserId == plr.UserId)))
48 | {
49 | response = "You are already part of a jail.";
50 | return false;
51 | }
52 |
53 | AdminToyBase adminToyBase = null;
54 | foreach (GameObject gameObject in NetworkClient.prefabs.Values)
55 | {
56 | if (gameObject == null)
57 | continue;
58 | AdminToyBase component;
59 | if (gameObject.TryGetComponent(out component))
60 | {
61 | if (string.Equals("LightSource", component.CommandName, StringComparison.InvariantCultureIgnoreCase))
62 | {
63 | adminToyBase = UnityEngine.Object.Instantiate(component);
64 | adminToyBase.transform.position = loc.SpawnPosition;
65 | NetworkServer.Spawn(adminToyBase.gameObject);
66 | }
67 | }
68 | }
69 |
70 | var sit = new AdminSit()
71 | {
72 | AssociatedReportId = 0,
73 | InitialDuration = 0,
74 | InitialReason = "",
75 | Location = loc,
76 | SpawnedObjects = new List()
77 | {
78 | adminToyBase,
79 | },
80 | Players = new List()
81 | };
82 |
83 | AdminSitHandler.Singleton.Sits.Add(sit);
84 |
85 | loc.InUse = true;
86 |
87 | JailParentCommand.AddPlr(plr, sit);
88 |
89 | response = "";
90 | foreach (var plr1 in arguments)
91 | {
92 | Player cmPlr = CedModPlayer.Get(plr1);
93 | if (cmPlr == null)
94 | {
95 | response += $"{plr1} Could not be found!\n";
96 | }
97 |
98 | JailParentCommand.AddPlr(cmPlr, sit);
99 | }
100 |
101 | response += "Jail assigned. Use jail add {playerId} to add someone and jail remove {playerId}";
102 | return false;
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/CedMod/Addons/AdminSitSystem/Commands/Jail/Delete.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CommandSystem;
4 | using LabApi.Features.Permissions;
5 | using MEC;
6 |
7 | namespace CedMod.Addons.AdminSitSystem.Commands.Jail
8 | {
9 | public class Delete : ICommand
10 | {
11 | public string Command { get; } = "delete";
12 |
13 | public string[] Aliases { get; } = {
14 | "d"
15 | };
16 |
17 | public string Description { get; } = "Removes all players currently in a jail and deletes the jail.";
18 |
19 | public bool Execute(ArraySegment arguments, ICommandSender sender, out string response)
20 | {
21 | if (!sender.HasPermissions("cedmod.jail"))
22 | {
23 | response = "no permission";
24 | return false;
25 | }
26 |
27 | var invoker = CedModPlayer.Get((sender as CommandSender).SenderId);
28 | if (!AdminSitHandler.Singleton.Sits.Any(s => s.Players.Any(s => s.UserId == invoker.UserId)))
29 | {
30 | response = "You are currently not part of any jail.";
31 | return false;
32 | }
33 |
34 | if (invoker == null)
35 | {
36 | response = $"Invoker could not be found.";
37 | return false;
38 | }
39 |
40 | var sit = AdminSitHandler.Singleton.Sits.FirstOrDefault(s => s.Players.Any(s => s.UserId == invoker.UserId));
41 |
42 | foreach (var plr in sit.Players)
43 | {
44 | var cmPlr = CedModPlayer.Get(plr.UserId);
45 | if (cmPlr == null)
46 | continue;
47 |
48 | JailParentCommand.RemovePlr(cmPlr, plr, sit);
49 | }
50 |
51 | Timing.CallDelayed(0.5f, () =>
52 | {
53 | JailParentCommand.RemoveJail(sit);
54 | });
55 |
56 | response = "Jail Removed";
57 | return false;
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/CedMod/Addons/AdminSitSystem/Commands/Jail/Join.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CommandSystem;
4 | using LabApi.Features.Permissions;
5 |
6 | namespace CedMod.Addons.AdminSitSystem.Commands.Jail
7 | {
8 | public class Join : ICommand
9 | {
10 | public string Command { get; } = "join";
11 |
12 | public string[] Aliases { get; } = {
13 | "j"
14 | };
15 |
16 | public string Description { get; } = "Adds yourself to the jail of the specified player";
17 |
18 | public bool Execute(ArraySegment arguments, ICommandSender sender,
19 | out string response)
20 | {
21 | if (!sender.HasPermissions("cedmod.jail"))
22 | {
23 | response = "no permission";
24 | return false;
25 | }
26 |
27 | if (arguments.Count < 1)
28 | {
29 | response = "This command requires a PlayerId to be specified";
30 | return false;
31 | }
32 |
33 | var invoker = CedModPlayer.Get((sender as CommandSender).SenderId);
34 | var plr = CedModPlayer.Get(arguments.At(0));
35 | if (plr == null)
36 | {
37 | response = $"Player '{arguments.At(0)}' could not be found.";
38 | return false;
39 | }
40 |
41 | if (invoker == null)
42 | {
43 | response = $"Invoker could not be found.";
44 | return false;
45 | }
46 |
47 | if (!AdminSitHandler.Singleton.Sits.Any(s => s.Players.Any(s => s.UserId == plr.UserId)))
48 | {
49 | response = "The specified player is not part of any jail.";
50 | return false;
51 | }
52 |
53 | var sit = AdminSitHandler.Singleton.Sits.FirstOrDefault(s => s.Players.Any(s => s.UserId == plr.UserId));
54 |
55 | JailParentCommand.AddPlr(invoker, sit);
56 |
57 | response = "Added, use jail remove {playerId} to remove yourself";
58 | return false;
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/CedMod/Addons/AdminSitSystem/Commands/Jail/Remove.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CommandSystem;
4 | using LabApi.Features.Permissions;
5 | using MEC;
6 |
7 | namespace CedMod.Addons.AdminSitSystem.Commands.Jail
8 | {
9 | public class Remove : ICommand
10 | {
11 | public string Command { get; } = "remove";
12 |
13 | public string[] Aliases { get; } = {
14 | "r"
15 | };
16 |
17 | public string Description { get; } = "Removes the specified player from your current jail.";
18 |
19 | public bool Execute(ArraySegment arguments, ICommandSender sender,
20 | out string response)
21 | {
22 | if (!sender.HasPermissions("cedmod.jail"))
23 | {
24 | response = "no permission";
25 | return false;
26 | }
27 |
28 | if (arguments.Count < 1)
29 | {
30 | response = "This command requires a PlayerId to be specified";
31 | return false;
32 | }
33 |
34 | var invoker = CedModPlayer.Get((sender as CommandSender).SenderId);
35 | if (!AdminSitHandler.Singleton.Sits.Any(s => s.Players.Any(s => s.UserId == invoker.UserId)))
36 | {
37 | response = "You are currently not part of any jail.";
38 | return false;
39 | }
40 |
41 | var plr = CedModPlayer.Get(arguments.At(0));
42 | if (plr == null)
43 | {
44 | response = $"Player '{arguments.At(0)}' could not be found.";
45 | return false;
46 | }
47 | var sit = AdminSitHandler.Singleton.Sits.FirstOrDefault(s => s.Players.Any(s => s.UserId == plr.UserId));
48 | if (sit == null)
49 | {
50 | response = "This player is not in a jail.";
51 | return false;
52 | }
53 |
54 | var sitPlr = sit.Players.First(s => s.UserId == plr.UserId);
55 | JailParentCommand.RemovePlr(plr, sitPlr, sit);
56 |
57 | Timing.CallDelayed(0.3f, () =>
58 | {
59 | if (!sit.Players.Any(s => s.PlayerType == AdminSitPlayerType.Staff || s.PlayerType == AdminSitPlayerType.Handler))
60 | {
61 | foreach (var sitPlr2 in sit.Players)
62 | {
63 | var plr2 = CedModPlayer.Get(sitPlr2.UserId);
64 | JailParentCommand.RemovePlr(plr2, sitPlr2, sit);
65 | }
66 |
67 | Timing.CallDelayed(0.5f, () =>
68 | {
69 | JailParentCommand.RemoveJail(sit);
70 | });
71 | }
72 | });
73 |
74 | response = "Player Removed";
75 | return false;
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Audio/CustomAudioPlayer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Net.Http;
7 | using System.Text;
8 | using LabApi.Features.Console;
9 | using MEC;
10 | using SCPSLAudioApi.AudioCore;
11 | using VoiceChat;
12 | using Random = UnityEngine.Random;
13 |
14 | namespace CedMod.Addons.Audio
15 | {
16 | using CedMod.Addons.QuerySystem;
17 |
18 | public class CustomAudioPlayer: AudioPlayerBase
19 | {
20 | public static CustomAudioPlayer Get(ReferenceHub hub)
21 | {
22 | if (AudioPlayers.TryGetValue(hub, out AudioPlayerBase player))
23 | {
24 | if (player is CustomAudioPlayer cplayer1)
25 | return cplayer1;
26 | }
27 |
28 | var cplayer = hub.gameObject.AddComponent();
29 | cplayer.Owner = hub;
30 | cplayer.BroadcastChannel = VoiceChatChannel.Proximity;
31 |
32 | AudioPlayers.Add(hub, cplayer);
33 | return cplayer;
34 | }
35 |
36 | public override IEnumerator Playback(int index)
37 | {
38 | if (Shuffle)
39 | AudioToPlay = AudioToPlay.OrderBy(i => Random.value).ToList();
40 | CurrentPlay = AudioToPlay[index];
41 | AudioToPlay.RemoveAt(index);
42 | if (Loop)
43 | {
44 | AudioToPlay.Add(CurrentPlay);
45 | }
46 |
47 | Logger.Info($"Loading Audio");
48 | byte[] respString;
49 | HttpStatusCode code = HttpStatusCode.OK;
50 | using (HttpClient client = new HttpClient())
51 | {
52 | client.DefaultRequestHeaders.Add("X-ServerIp", ServerConsole.Ip);
53 | var t = VerificationChallenge.AwaitVerification();
54 | yield return Timing.WaitUntilTrue(() => t.IsCompleted);
55 |
56 | var respTask = client.GetAsync($"http{(QuerySystem.UseSSL ? "s" : "")}://" + QuerySystem.CurrentMaster + $"/Api/v3/RetrieveAudio/{QuerySystem.QuerySystemKey}?track={CurrentPlay}");
57 | yield return Timing.WaitUntilTrue(() => respTask.IsCompleted);
58 | var resp = respTask.Result;
59 | var respStringTask = resp.Content.ReadAsByteArrayAsync();
60 | yield return Timing.WaitUntilTrue(() => respStringTask.IsCompleted);
61 | respString = respStringTask.Result;
62 | code = resp.StatusCode;
63 | }
64 |
65 | int cnt;
66 | if (code != HttpStatusCode.OK)
67 | {
68 | Logger.Error($"Failed to retrieve audio {code} {Encoding.UTF8.GetString(respString)}");
69 | if (Continue && AudioToPlay.Count >= 1)
70 | {
71 | yield return Timing.WaitForSeconds(1);
72 | Timing.RunCoroutine(Playback(0));
73 | }
74 | yield break;
75 | }
76 |
77 | try
78 | {
79 | CurrentPlayStream = new MemoryStream(respString);
80 | CurrentPlayStream.Seek(0, SeekOrigin.Begin);
81 | }
82 | catch (Exception e)
83 | {
84 | Logger.Error($"{e} {code} {Encoding.UTF8.GetString(respString)}");
85 | }
86 |
87 | VorbisReader = new NVorbis.VorbisReader(CurrentPlayStream);
88 | Logger.Info($"Playing with samplerate of {VorbisReader.SampleRate}");
89 | samplesPerSecond = VoiceChatSettings.SampleRate * VoiceChatSettings.Channels;
90 | //_samplesPerSecond = VorbisReader.Channels * VorbisReader.SampleRate / 5;
91 | SendBuffer = new float[samplesPerSecond / 5 + HeadSamples];
92 | ReadBuffer = new float[samplesPerSecond / 5 + HeadSamples];
93 |
94 | while ((cnt = VorbisReader.ReadSamples(ReadBuffer, 0, ReadBuffer.Length)) > 0)
95 | {
96 | if (stopTrack)
97 | {
98 | VorbisReader.SeekTo(VorbisReader.TotalSamples - 1);
99 | stopTrack = false;
100 | }
101 | while (!ShouldPlay)
102 | {
103 | yield return Timing.WaitForOneFrame;
104 | }
105 | while (StreamBuffer.Count >= ReadBuffer.Length)
106 | {
107 | ready = true;
108 | yield return Timing.WaitForOneFrame;
109 | }
110 | for (int i = 0; i < ReadBuffer.Length; i++)
111 | {
112 | StreamBuffer.Enqueue(ReadBuffer[i]);
113 | }
114 | }
115 | Logger.Info($"Track Complete.");
116 |
117 | if (Continue && AudioToPlay.Count >= 1)
118 | {
119 | Timing.RunCoroutine(Playback(0));
120 | }
121 | yield break;
122 | }
123 | }
124 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Audio/FakeConnection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Mirror;
3 |
4 | namespace CedMod.Addons.Audio
5 | {
6 | public class FakeConnection : NetworkConnectionToClient
7 | {
8 | public FakeConnection(int connectionId) : base(connectionId)
9 | {
10 |
11 | }
12 |
13 | public override string address
14 | {
15 | get
16 | {
17 | return "localhost";
18 | }
19 | }
20 |
21 | public override void Send(ArraySegment segment, int channelId = 0)
22 | {
23 | }
24 |
25 | public override void Disconnect()
26 | {
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Commands/BumpEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CedMod.Addons.Events.Interfaces;
4 | using CedMod.Addons.QuerySystem;
5 | using CommandSystem;
6 | using LabApi.Features.Permissions;
7 | using LabApi.Features.Wrappers;
8 | using MEC;
9 |
10 | namespace CedMod.Addons.Events.Commands
11 | {
12 | public class BumpEvent : ICommand, IUsageProvider
13 | {
14 | public string Command { get; } = "bump";
15 |
16 | public string[] Aliases { get; } = new string[]
17 | {
18 | };
19 |
20 | public string Description { get; } = "moves an event to the front of the queue";
21 |
22 | public string[] Usage { get; } = new string[]
23 | {
24 | "%eventprefix%",
25 | "%force%"
26 | };
27 |
28 | public bool Execute(ArraySegment arguments, ICommandSender sender,
29 | out string response)
30 | {
31 | if (arguments.Count < 2)
32 | {
33 | response = "To execute this command provide at least 2 arguments!\nUsage: " + this.DisplayCommandUsage();
34 | return false;
35 | }
36 | IEvent @event = EventManager.AvailableEvents.FirstOrDefault(ev => ev.EventPrefix == arguments.At(0));
37 | bool force = Convert.ToBoolean(arguments.At(1));
38 | if (@event == null)
39 | {
40 | response = "Event does not exist";
41 | return false;
42 | }
43 |
44 | if (sender.IsPanelUser() ? !sender.CheckPermission(PlayerPermissions.FacilityManagement) : !sender.HasPermissions("cedmod.events.bump"))
45 | {
46 | response = "No permission";
47 | return false;
48 | }
49 |
50 | EventManager.EventQueue.RemoveAll(ev => ev.EventName == @event.EventName);
51 | EventManager.EventQueue.Insert(0, @event);
52 |
53 | if (force)
54 | {
55 |
56 | Broadcast.Singleton.RpcAddElement($"EventManager: {@event.EventName} is being enabled.\nRound will restart in 3 seconds", 5, Broadcast.BroadcastFlags.Normal);
57 | Timing.CallDelayed(3, () =>
58 | {
59 | Round.Restart(false, false);
60 | });
61 | }
62 | else
63 | {
64 | Broadcast.Singleton.RpcAddElement($"EventManager: {@event.EventName} has been moved to queue position {EventManager.EventQueue.IndexOf(@event)}", 10, Broadcast.BroadcastFlags.Normal);
65 | }
66 | ThreadDispatcher.SendHeartbeatMessage(true);
67 | response = "Success";
68 | return true;
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Commands/DisableEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CedMod.Addons.QuerySystem;
3 | using CommandSystem;
4 | using LabApi.Features.Permissions;
5 | using LabApi.Features.Wrappers;
6 | using MEC;
7 |
8 | namespace CedMod.Addons.Events.Commands
9 | {
10 | public class DisableEvent : ICommand, IUsageProvider
11 | {
12 | public string Command { get; } = "disable";
13 |
14 | public string[] Aliases { get; } = new string[]
15 | {
16 | };
17 |
18 | public string Description { get; } = "Disables the current event will restart the round immediately";
19 |
20 | public string[] Usage { get; } = new string[]
21 | {
22 | "%queuepos%",
23 | };
24 |
25 | public bool Execute(ArraySegment arguments, ICommandSender sender,
26 | out string response)
27 | {
28 | if (arguments.Count < 1)
29 | {
30 | response = "To execute this command provide at least 1 arguments!\nUsage: " + this.DisplayCommandUsage();
31 | return false;
32 | }
33 | int queuepos = Convert.ToInt16(arguments.At(0));
34 | if (queuepos >= 1 && EventManager.EventQueue.Count <= 0)
35 | {
36 | if (EventManager.EventQueue.Count == 0)
37 | {
38 | response = "There is no event pending for the next round";
39 | return false;
40 | }
41 | }
42 | else if (queuepos <= 0)
43 | {
44 | if (EventManager.CurrentEvent == null)
45 | {
46 | response = "There is no event in progress";
47 | return false;
48 | }
49 | }
50 |
51 | if (sender.IsPanelUser() ? !sender.CheckPermission(PlayerPermissions.FacilityManagement) : !sender.HasPermissions("cedmod.events.disable"))
52 | {
53 | response = "No permission";
54 | return false;
55 | }
56 |
57 | if (queuepos >= 1)
58 | {
59 | var toRemove = EventManager.EventQueue[queuepos - 1];
60 | EventManager.EventQueue.Remove(toRemove);
61 | Broadcast.Singleton.RpcAddElement($"EventManager: {toRemove.EventName} has been removed from the queue", 5, Broadcast.BroadcastFlags.Normal);
62 | }
63 | else
64 | {
65 | Broadcast.Singleton.RpcAddElement($"EventManager: {EventManager.CurrentEvent.EventName} is being now disabled, round will restart in 3 seconds", 10, Broadcast.BroadcastFlags.Normal);
66 | Timing.CallDelayed(3, () =>
67 | {
68 | Round.Restart(false, false);
69 | });
70 | }
71 | ThreadDispatcher.SendHeartbeatMessage(true);
72 | response = "Success";
73 | return true;
74 | }
75 | }
76 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Commands/EnableEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CedMod.Addons.Events.Interfaces;
4 | using CedMod.Addons.QuerySystem;
5 | using CommandSystem;
6 | using LabApi.Features.Permissions;
7 | using LabApi.Features.Wrappers;
8 | using MEC;
9 |
10 | namespace CedMod.Addons.Events.Commands
11 | {
12 | public class EnableEvent : ICommand, IUsageProvider
13 | {
14 | public string Command { get; } = "enable";
15 |
16 | public string[] Aliases { get; } = new string[]
17 | {
18 | };
19 |
20 | public string Description { get; } = "Enables the specified event, if Force is true the server will restart the round immediately";
21 |
22 | public string[] Usage { get; } = new string[]
23 | {
24 | "%eventprefix%",
25 | "%force%"
26 | };
27 |
28 | public bool Execute(ArraySegment arguments, ICommandSender sender,
29 | out string response)
30 | {
31 | if (arguments.Count < 2)
32 | {
33 | response = "To execute this command provide at least 2 arguments!\nUsage: " + this.DisplayCommandUsage();
34 | return false;
35 | }
36 | IEvent @event = EventManager.AvailableEvents.FirstOrDefault(ev => ev.EventPrefix == arguments.At(0));
37 | bool force = Convert.ToBoolean(arguments.At(1));
38 | if (@event == null)
39 | {
40 | response = "Event does not exist";
41 | return false;
42 | }
43 |
44 | if (sender.IsPanelUser() ? !sender.CheckPermission(PlayerPermissions.FacilityManagement) : !sender.HasPermissions("cedmod.events.enable"))
45 | {
46 | response = "No permission";
47 | return false;
48 | }
49 |
50 | if (force)
51 | {
52 | EventManager.EventQueue.RemoveAll(ev => ev.EventName == @event.EventName);
53 | EventManager.EventQueue.Insert(0, @event);
54 | Broadcast.Singleton.RpcAddElement($"EventManager: {@event.EventName} is being enabled.\nRound will restart in 3 seconds", 5, Broadcast.BroadcastFlags.Normal);
55 | Timing.CallDelayed(3, () =>
56 | {
57 | Round.Restart(false, false);
58 | });
59 | }
60 | else
61 | {
62 | if (EventManager.EventQueue.Any(ev => ev.EventName == @event.EventName))
63 | {
64 | response = "This event is already added to the queue";
65 | return false;
66 | }
67 | EventManager.EventQueue.Add(@event);
68 | Broadcast.Singleton.RpcAddElement($"EventManager: {@event.EventName} has been added to the event queue: position {EventManager.EventQueue.IndexOf(@event)}", 10, Broadcast.BroadcastFlags.Normal);
69 | }
70 | ThreadDispatcher.SendHeartbeatMessage(true);
71 | response = "Success";
72 | return true;
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Commands/Events.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CommandSystem;
3 |
4 | namespace CedMod.Addons.Events.Commands
5 | {
6 | [CommandHandler(typeof(RemoteAdminCommandHandler))]
7 | public class EventsCommand : ParentCommand
8 | {
9 | public override string Command => "events";
10 |
11 | public override string[] Aliases { get; } = new string[]
12 | {
13 | };
14 | public override string Description => "Main command for CedMod EventSystem";
15 |
16 | public EventsCommand() => LoadGeneratedCommands();
17 |
18 | public override void LoadGeneratedCommands()
19 | {
20 | RegisterCommand(new ListEvents());
21 | RegisterCommand(new EnableEvent());
22 | RegisterCommand(new DisableEvent());
23 | RegisterCommand(new Queue());
24 | RegisterCommand(new BumpEvent());
25 | }
26 |
27 | protected override bool ExecuteParent(ArraySegment arguments, ICommandSender sender, out string response)
28 | {
29 |
30 | response = "Please specify a valid subcommand!\n Valid subcommands are: list, enable, disable, queue, bump";
31 | return false;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Commands/ListEvents.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CommandSystem;
3 | using LabApi.Features.Permissions;
4 |
5 | namespace CedMod.Addons.Events.Commands
6 | {
7 | public class ListEvents : ICommand
8 | {
9 | public string Command { get; } = "list";
10 |
11 | public string[] Aliases { get; } = new string[]
12 | {
13 | };
14 |
15 | public string Description { get; } = "Gets a list of events";
16 |
17 | public bool Execute(ArraySegment arguments, ICommandSender sender,
18 | out string response)
19 | {
20 | response = "";
21 | if (!sender.HasPermissions("cedmod.events.list"))
22 | {
23 | response = "No permission";
24 | return false;
25 | }
26 | foreach (var ev in EventManager.AvailableEvents)
27 | {
28 | response += $"{ev.EventName} (Prefix: {ev.EventPrefix}) Author: {ev.EvenAuthor} - {ev.EventDescription}";
29 | }
30 |
31 | return true;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Commands/PopuplateCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using CedMod.Addons.Audio;
5 | using CentralAuth;
6 | using CommandSystem;
7 | using LabApi.Features.Permissions;
8 | using MEC;
9 | using Mirror;
10 | using Object = UnityEngine.Object;
11 |
12 | namespace CedMod.Addons.Events.Commands
13 | {
14 | [CommandHandler(typeof(RemoteAdminCommandHandler))]
15 | public class Populate : ICommand, IUsageProvider
16 | {
17 | public string Command { get; } = "populate";
18 |
19 | public string[] Aliases { get; } = new string[]
20 | {
21 | };
22 |
23 | public string Description { get; } = "spawns an given amount of dummy players for testing purposes.";
24 |
25 | public string[] Usage { get; } = new string[]
26 | {
27 | "%amount%",
28 | };
29 |
30 | public bool Execute(ArraySegment arguments, ICommandSender sender, out string response)
31 | {
32 | if (!sender.HasPermissions("cedmod.populate"))
33 | {
34 | response = "no permission";
35 | return false;
36 | }
37 | if (arguments.Count < 1)
38 | {
39 | response = "To execute this command provide at least 1 argument!\nUsage: " + this.DisplayCommandUsage();
40 | return false;
41 | }
42 | int amount = Convert.ToInt16(arguments.At(0));
43 |
44 | Timing.RunCoroutine(SpawnDummies(amount));
45 | response = "Success";
46 | return true;
47 | }
48 |
49 | public IEnumerator SpawnDummies(int amount)
50 | {
51 | var first = AudioCommand.FakeConnectionsIds.OrderByDescending(s => s.Key);
52 | var id = AudioCommand.FakeConnectionsIds.Count <= 0 ? 1 : first.FirstOrDefault().Key;
53 | while (id < amount)
54 | {
55 | id++;
56 | var newPlayer = Object.Instantiate(NetworkManager.singleton.playerPrefab);
57 |
58 | var fakeConnection = new FakeConnection(id);
59 |
60 |
61 | var hubPlayer = newPlayer.GetComponent();
62 | AudioCommand.FakeConnections.Add(fakeConnection, hubPlayer);
63 | AudioCommand.FakeConnectionsIds.Add(id, hubPlayer);
64 |
65 | NetworkServer.AddPlayerForConnection(fakeConnection, newPlayer);
66 | try
67 | {
68 | hubPlayer.authManager.UserId = $"player{id}@server";
69 | }
70 | catch (Exception e)
71 | {
72 | }
73 | hubPlayer.authManager.InstanceMode = ClientInstanceMode.Host;
74 | try
75 | {
76 | hubPlayer.nicknameSync.SetNick($"Dummy player {id}");
77 | }
78 | catch (Exception e)
79 | {
80 | }
81 |
82 | yield return Timing.WaitForSeconds(0.05f);
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Commands/Queue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CedMod.Addons.QuerySystem;
3 | using CommandSystem;
4 | using LabApi.Features.Permissions;
5 |
6 | namespace CedMod.Addons.Events.Commands
7 | {
8 | public class Queue : ICommand
9 | {
10 | public string Command { get; } = "queue";
11 |
12 | public string[] Aliases { get; } = new string[]
13 | {
14 | };
15 |
16 | public string Description { get; } = "Gets the current event queue";
17 |
18 | public bool Execute(ArraySegment arguments, ICommandSender sender,
19 | out string response)
20 | {
21 | if (sender.IsPanelUser() ? !sender.CheckPermission(PlayerPermissions.FacilityManagement) : !sender.HasPermissions("cedmod.events.queue"))
22 | {
23 | response = "No permission";
24 | return false;
25 | }
26 |
27 | response = "";
28 | response += $"Current event: [0] {(EventManager.CurrentEvent == null ? "None" : $"{EventManager.CurrentEvent.EventName} - ({EventManager.CurrentEvent.EventPrefix})")}\n\n\nQueue:\n";
29 | foreach (var evnt in EventManager.EventQueue)
30 | {
31 | response += $"[{EventManager.EventQueue.IndexOf(evnt) + 1}] {evnt.EventName} - ({evnt.EventPrefix})\n";
32 | }
33 | ThreadDispatcher.SendHeartbeatMessage(true);
34 | return true;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Config.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace CedMod.Addons.Events
4 | {
5 | public sealed class EventsConfig
6 | {
7 | [Description("Indicates whether the plugin is enabled or not")]
8 | public bool IsEnabled { get; set; } = true;
9 |
10 | [Description("If debug messages are shown")]
11 | public bool Debug { get; set; } = false;
12 | }
13 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/EventManager.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using CedMod.Addons.Events.Interfaces;
3 | using Exiled.API.Interfaces;
4 | using LabApi.Loader.Features.Plugins;
5 |
6 | namespace CedMod.Addons.Events
7 | {
8 | public class EventManager
9 | {
10 | public static IEvent CurrentEvent = null;
11 | public static List EventQueue = new List();
12 | public static List AvailableEvents = new List();
13 | public static List AvailableEventPlugins = new List();
14 | #if EXILED
15 | public static List> AvailableEventPluginsExiled = new List>();
16 | #endif
17 | }
18 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/EventManagerPlayerEvents.cs:
--------------------------------------------------------------------------------
1 | using LabApi.Events.Arguments.PlayerEvents;
2 | using LabApi.Events.CustomHandlers;
3 | using LabApi.Features.Console;
4 |
5 | namespace CedMod.Addons.Events
6 | {
7 | public class EventManagerPlayerEvents: CustomEventsHandler
8 | {
9 | public override void OnPlayerJoined(PlayerJoinedEventArgs ev)
10 | {
11 | if (CedModMain.Singleton.Config.EventManager.Debug)
12 | Logger.Debug($"Join {EventManager.CurrentEvent != null}");
13 | if (EventManager.CurrentEvent != null)
14 | {
15 | ev.Player.GameObject.AddComponent();
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/EventManagerServerEvents.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using CedMod.Addons.Events.Interfaces;
5 | using CedMod.Addons.Events.Patches;
6 | using CedMod.Addons.QuerySystem;
7 | #if EXILED
8 | using Exiled.API.Features;
9 | #endif
10 | using LabApi.Events.Arguments.ServerEvents;
11 | using LabApi.Events.CustomHandlers;
12 | using LabApi.Features.Console;
13 |
14 | namespace CedMod.Addons.Events
15 | {
16 | public class EventManagerServerEvents: CustomEventsHandler
17 | {
18 | public override void OnServerRoundEnding(RoundEndingEventArgs ev)
19 | {
20 | if (EventManager.CurrentEvent != null && EventManager.CurrentEvent is IEndConditionBehaviour endConditionBehaviour)
21 | {
22 | ev.IsAllowed = endConditionBehaviour.CanRoundEnd(false);
23 | }
24 | }
25 |
26 | public override void OnServerRoundEnded(RoundEndedEventArgs ev)
27 | {
28 | if (EventManager.CurrentEvent != null)
29 | {
30 | Logger.Info($"Enabled {EventManager.CurrentEvent.EventName} has been disabled due to round end");
31 | EventManager.CurrentEvent.StopEvent();
32 | EventManager.CurrentEvent = null;
33 | }
34 | }
35 |
36 | public override void OnServerWaitingForPlayers()
37 | {
38 | if (EventManager.EventQueue.Count >= 1)
39 | {
40 | var next = EventManager.EventQueue.FirstOrDefault();
41 | EventManager.CurrentEvent = next;
42 | EventManager.EventQueue.Remove(next);
43 | }
44 | if (EventManager.CurrentEvent != null)
45 | {
46 | EventManager.CurrentEvent.PrepareEvent();
47 | Logger.Info($"Enabled {EventManager.CurrentEvent.EventName} for this round");
48 | }
49 | ThreadDispatcher.SendHeartbeatMessage(true);
50 |
51 | #if EXILED
52 | if (AppDomain.CurrentDomain.GetAssemblies().Any(s => s.GetName().Name == "ScriptedEvents") && Directory.Exists(Path.Combine(Paths.Configs, "ScriptedEvents")) && EventManager.EventQueue.Count == 0)
53 | {
54 | EventManager.AvailableEvents.RemoveAll(s => s.GetType() == typeof(ScriptedEventIntergration));
55 | foreach (var file in Directory.GetFiles(Path.Combine(Paths.Configs, "ScriptedEvents")))
56 | {
57 | string data = File.ReadAllText(file);
58 | if (!data.Contains("!-- DISABLE") && data.Contains("!-- ADMINEVENT"))
59 | {
60 | EventManager.AvailableEvents.Add(new ScriptedEventIntergration()
61 | {
62 | BulletHolesAllowed = true,
63 | config = new ScriptedEventConfig(){ IsEnabled = true},
64 | eventAuthor = "ScriptedEvents",
65 | EventDescription = "ScriptedEvent",
66 | eventName = Path.GetFileNameWithoutExtension(file),
67 | eventPrefix = Path.GetFileNameWithoutExtension(file),
68 | FilePath = file
69 | });
70 | }
71 | }
72 | }
73 | #endif
74 | }
75 |
76 | public override void OnServerRoundRestarted()
77 | {
78 | if (EventManager.CurrentEvent != null)
79 | {
80 | Logger.Info($"Enabled {EventManager.CurrentEvent.EventName} has been disabled due to round restart");
81 | EventManager.CurrentEvent.StopEvent();
82 | EventManager.CurrentEvent = null;
83 | }
84 | HintManager.HintProcessed.Clear();
85 |
86 | SeedGenerationPatch.NextSeed = -1;
87 |
88 | if (EventManager.EventQueue.Count >= 1)
89 | {
90 | var next = EventManager.EventQueue.FirstOrDefault();
91 | if (next is IMapgenBehaviour mapgenBehaviour)
92 | {
93 | SeedGenerationPatch.NextSeed = mapgenBehaviour.Seed;
94 | }
95 | }
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/HintManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using LabApi.Features.Wrappers;
4 | using UnityEngine;
5 |
6 | namespace CedMod.Addons.Events
7 | {
8 | public class HintManager: MonoBehaviour
9 | {
10 | public float hintTimer = 0;
11 | public float hintRefreshRate = 1;
12 | public static List> HintProcessed = new List>();
13 | public Player player;
14 | public string currentHint = "";
15 | private bool wipe = false;
16 |
17 | public void Awake()
18 | {
19 | player = Player.Get(this.GetComponent());
20 | LabApi.Features.Console.Logger.Info($"Initialized HintManager for {player.Nickname}");
21 | currentHint = "\n\n" +
22 | "This server is currently running an event:" +
23 | $"\n{EventManager.CurrentEvent.EventName} By {EventManager.CurrentEvent.EvenAuthor}" +
24 | $"\n" +
25 | $"\n{EventManager.CurrentEvent.EventDescription}" +
26 | $"";
27 | }
28 |
29 | public void Update()
30 | {
31 | if (!wipe && RoundSummary.RoundInProgress())
32 | {
33 | wipe = true;
34 | currentHint = "";
35 | }
36 | hintTimer -= Time.deltaTime;
37 | if (hintTimer <= 0)
38 | {
39 | hintTimer = hintRefreshRate - 0.2f;
40 | string hintAddition = "";
41 | foreach (var callback in HintProcessed)
42 | {
43 | hintAddition += callback.Invoke(player);
44 | }
45 |
46 | if (HintProcessed.Count >= 1)
47 | {
48 | if (!string.IsNullOrEmpty(hintAddition))
49 | currentHint = hintAddition;
50 |
51 | if (string.IsNullOrEmpty(hintAddition))
52 | currentHint = "";
53 | }
54 |
55 | if (CedModMain.Singleton.Config.EventManager.Debug)
56 | LabApi.Features.Console.Logger.Debug($"Hint display: {currentHint}");
57 |
58 | if (!string.IsNullOrEmpty(currentHint))
59 | player.SendHint(currentHint, hintRefreshRate);
60 | }
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/IEventConfig.cs:
--------------------------------------------------------------------------------
1 | namespace CedMod.Addons.Events
2 | {
3 | public interface IEventConfig
4 | {
5 | public bool IsEnabled { get; set; }
6 | }
7 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Interfaces/IBulletHoleBehaviour.cs:
--------------------------------------------------------------------------------
1 | using InventorySystem.Items.Firearms.Modules;
2 | using UnityEngine;
3 |
4 | namespace CedMod.Addons.Events.Interfaces
5 | {
6 | public interface IBulletHoleBehaviour
7 | {
8 | bool CanPlaceBulletHole(ImpactEffectsModule reg, Vector3 ray, RaycastHit hit);
9 | }
10 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Interfaces/IEndConditionBehaviour.cs:
--------------------------------------------------------------------------------
1 | namespace CedMod.Addons.Events.Interfaces
2 | {
3 | public interface IEndConditionBehaviour
4 | {
5 | bool CanRoundEnd(bool baseGameConditionsSatisfied);
6 | }
7 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Interfaces/IEvent.cs:
--------------------------------------------------------------------------------
1 | namespace CedMod.Addons.Events.Interfaces
2 | {
3 | public interface IEvent
4 | {
5 | string EventName { get; }
6 | string EvenAuthor { get; }
7 | string EventDescription { get; set; }
8 | string EventPrefix { get; }
9 | IEventConfig EventConfig { get; }
10 |
11 | void PrepareEvent();
12 | void StopEvent();
13 | }
14 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Interfaces/IFriendlyFireAutoBanBehaviour.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LabApi.Features.Wrappers;
3 | using PlayerStatsSystem;
4 |
5 | namespace CedMod.Addons.Events.Interfaces
6 | {
7 | public interface IFriendlyFireAutoBanBehaviour
8 | {
9 | string VictimMessage(Player player, Player attacker, DamageHandlerBase damageHandler);
10 | string KillerMessage(Player player, Player attacker, DamageHandlerBase damageHandler);
11 | bool IsTeamkill(Player player, Player attacker, DamageHandlerBase damageHandler);
12 | bool ShouldBan(Player player, Player attacker, DamageHandlerBase damageHandler, int teamkillAmount, out int cedModAutobanThreshold, out bool ignoreImmunity, out TimeSpan banDuration, out string banReason);
13 | }
14 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Interfaces/IMapgenBehaviour.cs:
--------------------------------------------------------------------------------
1 | namespace CedMod.Addons.Events.Interfaces
2 | {
3 | public interface IMapgenBehaviour
4 | {
5 | int Seed { get; set; }
6 | }
7 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Patches/BulletHolePatch.cs:
--------------------------------------------------------------------------------
1 | using CedMod.Addons.Events.Interfaces;
2 | using Decals;
3 | using HarmonyLib;
4 | using InventorySystem.Items.Firearms.Modules;
5 | using UnityEngine;
6 | using VoiceChat;
7 |
8 | namespace CedMod.Addons.Events.Patches
9 | {
10 | [HarmonyPatch(typeof(ImpactEffectsModule), nameof(ImpactEffectsModule.ServerSendImpactDecal))]
11 | public static class BulletHolePatch
12 | {
13 | public static bool Prefix(ImpactEffectsModule __instance, RaycastHit hit, Vector3 origin, DecalPoolType decalType)
14 | {
15 | if (CedModMain.Singleton.Config.CedMod.PreventBulletHolesWhenMuted && __instance.Firearm.Owner != null && VoiceChatMutes.GetFlags(__instance.Firearm.Owner).HasFlag(VcMuteFlags.LocalRegular))
16 | return false;
17 | if (EventManager.CurrentEvent != null && EventManager.CurrentEvent is IBulletHoleBehaviour dissallowBulletHoles && !dissallowBulletHoles.CanPlaceBulletHole(__instance, origin, hit))
18 | return false;
19 | return true;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/Patches/SeedGenerationPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using MapGeneration;
3 |
4 | namespace CedMod.Addons.Events.Patches
5 | {
6 | [HarmonyPatch(typeof(SeedSynchronizer), nameof(SeedSynchronizer.Awake))]
7 | public static class SeedGenerationPatch
8 | {
9 | private static int _nextSeed = -1;
10 |
11 | public static int NextSeed
12 | {
13 | private get => _nextSeed;
14 | set
15 | {
16 | if (value < 0)
17 | _nextSeed = -1;
18 | else
19 | _nextSeed = value;
20 | }
21 | }
22 |
23 | public static bool Prefix(SeedSynchronizer __instance)
24 | {
25 | if (NextSeed == -1)
26 | return true;
27 |
28 | SeedSynchronizer.Seed= NextSeed;
29 | return false;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/CedMod/Addons/Events/ScriptedEventIntergration.cs:
--------------------------------------------------------------------------------
1 | using CedMod.Addons.Events.Interfaces;
2 |
3 | namespace CedMod.Addons.Events
4 | {
5 | public class ScriptedEventIntergration: IEvent
6 | {
7 | public string FilePath { get; set; }
8 | public string EventName
9 | {
10 | get => eventName;
11 | }
12 | public string eventName;
13 | public string EvenAuthor
14 | {
15 | get => eventAuthor;
16 | }
17 | public string eventAuthor;
18 | public string EventDescription { get; set; } = "Scripted-Event";
19 | public string EventPrefix
20 | {
21 | get => $"SCRPTEV-{eventPrefix}";
22 | }
23 | public string eventPrefix;
24 | public bool BulletHolesAllowed { get; set; }
25 | public IEventConfig EventConfig
26 | {
27 | get => config;
28 | }
29 | public IEventConfig config;
30 | public void PrepareEvent()
31 | {
32 | #if EXILED
33 | var script = ScriptedEvents.API.Helpers.ScriptHelper.ReadScript(eventName);
34 | ScriptedEvents.API.Helpers.ScriptHelper.RunScript(script);
35 | #endif
36 | }
37 |
38 | public void StopEvent()
39 | {
40 | #if EXILED
41 | ScriptedEvents.API.Helpers.ScriptHelper.StopAllScripts();
42 | #endif
43 | }
44 | }
45 |
46 | public class ScriptedEventConfig : IEventConfig
47 | {
48 | public bool IsEnabled { get; set; }
49 | }
50 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Commands/CmSyncCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CommandSystem;
3 |
4 | namespace CedMod.Addons.QuerySystem.Commands
5 | {
6 | [CommandHandler(typeof(RemoteAdminCommandHandler))]
7 | public class CmSyncCommandCommand : ICommand
8 | {
9 | public string Command { get; } = "cmsync";
10 |
11 | public string[] Aliases { get; } = new string[]
12 | {
13 | };
14 |
15 | public string Description { get; } = "syncs roles for cedmod panel";
16 |
17 | public bool Execute(ArraySegment arguments, ICommandSender sender,
18 | out string response)
19 | {
20 | if (sender.IsPanelUser())
21 | {
22 | if (!sender.CheckPermission(PlayerPermissions.SetGroup))
23 | {
24 | response = "No permission";
25 | return false;
26 | }
27 | if (ServerStatic.PermissionsHandler.Members.ContainsKey(CedModPlayer.Get(int.Parse(arguments.At(0))).UserId))
28 | {
29 | response = "User already has a role";
30 | return false;
31 | }
32 |
33 | if (CedModPlayer.Get(int.Parse(arguments.At(0))).UserId != arguments.At(2))
34 | {
35 | response = "UserId mismatch";
36 | return false;
37 | }
38 | ServerStatic.PermissionsHandler.Members[CedModPlayer.Get(int.Parse(arguments.At(0))).UserId] = arguments.At(1);
39 | CedModPlayer.Get(int.Parse(arguments.At(0))).ReferenceHub.serverRoles.SetGroup(ServerStatic.PermissionsHandler.Groups[arguments.At(1)], false);
40 | CommandHandler.Synced.Add(CedModPlayer.Get(int.Parse(arguments.At(0))).UserId, arguments.At(1));
41 | response = "Done.";
42 | return true;
43 | }
44 |
45 | response = "This command may only be run by the panel";
46 | return true;
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Commands/ImportRaCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using CedMod.Addons.QuerySystem;
4 | using CedMod.Addons.QuerySystem.WS;
5 | using CedMod.ApiModals;
6 | using CommandSystem;
7 | using Newtonsoft.Json;
8 |
9 | namespace CedMod.Commands
10 | {
11 | [CommandHandler(typeof(GameConsoleCommandHandler))]
12 | public class ImportRaCommand : ICommand
13 | {
14 | public string Command { get; } = "cedmodimportra";
15 |
16 | public string[] Aliases { get; } = new string[]
17 | {
18 | };
19 |
20 | public string Description { get; } = "Import your RA configuration to CedMod, WARNING, will override current panel perms";
21 |
22 | public bool Execute(ArraySegment arguments, ICommandSender sender, out string response)
23 | {
24 | ThreadDispatcher.ThreadDispatchQueue.Enqueue(() =>
25 | {
26 | List Groups = new List();
27 | foreach (var group in ServerStatic.PermissionsHandler.Groups)
28 | {
29 | //var perms = Permissions.Groups.FirstOrDefault(s => s.Key == group.Key);
30 | Groups.Add(new SLPermissionEntry()
31 | {
32 | Name = group.Key,
33 | KickPower = group.Value.KickPower,
34 | RequiredKickPower = group.Value.RequiredKickPower,
35 | Hidden = group.Value.HiddenByDefault,
36 | Cover = group.Value.Cover,
37 | ReservedSlot = false,
38 | BadgeText = group.Value.BadgeText,
39 | BadgeColor = group.Value.BadgeColor,
40 | RoleId = 0,
41 | Permissions = (PlayerPermissions)group.Value.Permissions,
42 | ExiledPermissions = new List(),
43 | //perms.Value == null ? new List() : perms.Value.CombinedPermissions
44 | });
45 | }
46 |
47 | WebSocketSystem.Enqueue(new QueryCommand()
48 | {
49 | Recipient = "PANEL",
50 | Data = new Dictionary()
51 | {
52 | { "Message", "ImportRAResponse" },
53 | { "Data", JsonConvert.SerializeObject(Groups) }
54 | }
55 | });
56 | });
57 | response = "Done";
58 | return true;
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Commands/NearbyBulletHoles.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using CedMod.Addons.QuerySystem.Patches;
4 | using CommandSystem;
5 | using MapGeneration;
6 | using PluginAPI.Core;
7 | using RemoteAdmin;
8 | using NWAPIPermissionSystem;
9 |
10 | namespace CedMod.Addons.QuerySystem.Commands
11 | {
12 | [CommandHandler(typeof(RemoteAdminCommandHandler))]
13 | public class NearbyBulletHolesCommand : ICommand
14 | {
15 | public string Command { get; } = "nearbybulletholes";
16 |
17 | public string[] Aliases { get; } = new string[]
18 | {
19 | "bulletholes",
20 | "nearbyholes"
21 | };
22 |
23 | public string Description { get; } =
24 | "Shows the creators of the nearby bullet holes and how much the bullet holes were";
25 |
26 | public bool Execute(ArraySegment arguments, ICommandSender sender,
27 | out string response)
28 | {
29 | if (!sender.CheckPermission("cedmod.bulletholes"))
30 | {
31 | response = "No permission";
32 | return false;
33 | }
34 |
35 | response =
36 | "List of nearby bulletholes\nFormat: [Playername] ([PlayerId]) - [BulletHoleCreated] CON: [IsConnected]";
37 | var room = RoomIdUtils.RoomAtPosition(Player.Get((sender as PlayerCommandSender).ReferenceHub).Position);
38 | if (arguments.Count >= 1)
39 | {
40 | foreach (var creat in BulletHolePatch.HoleCreators.Where(hole =>
41 | hole.Key.Nickname == arguments.At(0) || hole.Key.PlayerId.ToString() == arguments.At(0)))
42 | {
43 | if (creat.Value.Rooms.ContainsKey(room))
44 | {
45 | response +=
46 | $"\n{creat.Key.Nickname} ({creat.Key.PlayerId}) - {creat.Value.Rooms[room].Holes.Count} CON: {creat.Key.ReferenceHub != null}";
47 | }
48 | }
49 |
50 | return true;
51 | }
52 | else
53 | {
54 | foreach (var creat in BulletHolePatch.HoleCreators)
55 | {
56 | if (creat.Value.Rooms.ContainsKey(room))
57 | {
58 | response +=
59 | $"\n{creat.Key.Nickname} ({creat.Key.PlayerId}) - {creat.Value.Rooms[room].Holes.Count} CON: {creat.Key.ReferenceHub != null}";
60 | }
61 | }
62 |
63 | return true;
64 | }
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Commands/RestartQuery.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using CedMod.Addons.QuerySystem.WS;
4 | using CommandSystem;
5 | using LabApi.Features.Permissions;
6 | #if !EXILED
7 |
8 | #else
9 | using Exiled.Permissions.Extensions;
10 | #endif
11 |
12 | namespace CedMod.Addons.QuerySystem.Commands
13 | {
14 | [CommandHandler(typeof(RemoteAdminCommandHandler))]
15 | public class RestartQueryCommand : ICommand
16 | {
17 | public string Command { get; } = "restartqueryserver";
18 |
19 | public string[] Aliases { get; } = new string[]
20 | {
21 | };
22 |
23 | public string Description { get; } = "restarts querysystem";
24 |
25 | public bool Execute(ArraySegment arguments, ICommandSender sender,
26 | out string response)
27 | {
28 | if (!sender.HasPermissions("cedmod.restartquery"))
29 | {
30 | response = "No permission";
31 | return false;
32 | }
33 |
34 | Task.Run(async () =>
35 | {
36 | WebSocketSystem.Stop();
37 | await WebSocketSystem.Start();
38 | });
39 | response = "Query server restarted";
40 | return true;
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Commands/ToggleExpTracking.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CedMod.Addons.QuerySystem.WS;
3 | using CommandSystem;
4 | using LabApi.Features.Permissions;
5 | #if !EXILED
6 | #else
7 | using Exiled.Permissions.Extensions;
8 | #endif
9 |
10 | namespace CedMod.Addons.QuerySystem.Commands
11 | {
12 | [CommandHandler(typeof(RemoteAdminCommandHandler))]
13 | public class TogglExptracking : ICommand
14 | {
15 | public string Command { get; } = "toggleexptracking";
16 |
17 | public string[] Aliases { get; } = new string[]
18 | {
19 | };
20 |
21 | public string Description { get; } = "Toggles tracking of EXP for this specific server";
22 |
23 | public bool Execute(ArraySegment arguments, ICommandSender sender,
24 | out string response)
25 | {
26 | if (!sender.HasPermissions("cedmod.exptoggle"))
27 | {
28 | response = "No permission";
29 | return false;
30 | }
31 |
32 | if (!WebSocketSystem.HelloMessage.ExpEnabled)
33 | {
34 | response = "EXP Tracking is disabled on panel level and cannot be enabled locally";
35 | return false;
36 | }
37 | LevelerStore.TrackingEnabled = !LevelerStore.TrackingEnabled;
38 | response = $"EXP tracking {(LevelerStore.TrackingEnabled ? "Enabled" : "Disabled")}";
39 | return true;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Extensions.cs:
--------------------------------------------------------------------------------
1 | using CedMod.Addons.QuerySystem.WS;
2 | using CommandSystem;
3 |
4 | namespace CedMod.Addons.QuerySystem
5 | {
6 | public static class Extensions
7 | {
8 | public static bool IsPanelUser(this ICommandSender sender)
9 | {
10 | return sender is CmSender;
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/LevelerStore.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using LabApi.Features.Wrappers;
3 | using PlayerRoles;
4 |
5 | namespace CedMod.Addons.QuerySystem
6 | {
7 | public class LevelerStore
8 | {
9 | public static bool TrackingEnabled;
10 | public static Dictionary InitialPlayerRoles = new Dictionary();
11 | }
12 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/BulletHolePatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using HarmonyLib;
4 | using InventorySystem.Items.Firearms.Modules;
5 | using MapGeneration;
6 | using PluginAPI.Core;
7 | using UnityEngine;
8 |
9 | namespace CedMod.Addons.QuerySystem.Patches
10 | {
11 | [HarmonyPatch(typeof(StandardHitregBase), nameof(StandardHitregBase.PlaceBulletholeDecal))]
12 | public static class BulletHolePatch
13 | {
14 | public static Dictionary HoleCreators = new Dictionary();
15 |
16 | public static void Prefix(StandardHitregBase __instance, Ray ray, RaycastHit hit)
17 | {
18 | try
19 | {
20 | Player player = Player.Get(__instance.Hub);
21 | if (player == null)
22 | return;
23 | RoomIdentifier currentRoom = RoomIdUtils.RoomAtPosition(player.Position);
24 | if (!HoleCreators.ContainsKey(player))
25 | HoleCreators.Add(player, new BulletHoleCreator());
26 | if (!HoleCreators[player].Rooms.ContainsKey(currentRoom))
27 | HoleCreators[player].Rooms.Add(currentRoom, new RoomHoles());
28 |
29 | HoleCreators[player].Rooms[currentRoom].Holes.Add(hit.point);
30 | }
31 | catch (Exception e)
32 | {
33 | if (CedModMain.Singleton.Config.QuerySystem.Debug)
34 | Log.Error(e.Message);
35 | }
36 | }
37 | }
38 |
39 | public class BulletHoleCreator
40 | {
41 | public Dictionary Rooms = new Dictionary();
42 | }
43 |
44 | public class RoomHoles
45 | {
46 | public List Holes = new List();
47 | }
48 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/CommandProcessorPatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using CedMod.Addons.QuerySystem.WS;
4 | using HarmonyLib;
5 | using LabApi.Features.Console;
6 | using RemoteAdmin;
7 |
8 | namespace CedMod.Addons.QuerySystem.Patches
9 | {
10 | [HarmonyPatch(typeof(CommandProcessor), nameof(CommandProcessor.ProcessQuery))]
11 | public static class CommandProcessorPatch
12 | {
13 | public static void Postfix(string q, CommandSender sender)
14 | {
15 | try
16 | {
17 | if (q.StartsWith("$", StringComparison.Ordinal))
18 | {
19 | return;
20 | }
21 |
22 | WebSocketSystem.Enqueue(new QueryCommand()
23 | {
24 | Recipient = "ALL",
25 | Data = new Dictionary()
26 | {
27 | {"Type", "OnAdminCommand"},
28 | {"UserId", sender.SenderId},
29 | {"UserName", sender.Nickname},
30 | {"Command", q},
31 | {
32 | "Message", string.Concat(new string[]
33 | {
34 | $"{sender.Nickname} ({sender.SenderId})",
35 | " used command: ",
36 | q
37 | })
38 | }
39 | }
40 | });
41 | }
42 | catch (Exception e)
43 | {
44 | Logger.Error(e.ToString());
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/ExiledPermissionsPatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using CedMod.Addons.QuerySystem.WS;
6 | using Exiled.API.Features;
7 | using Exiled.Permissions.Extensions;
8 | using Exiled.Permissions.Features;
9 | using GameCore;
10 | using HarmonyLib;
11 | using LabApi.Features.Console;
12 | using NorthwoodLib.Pools;
13 | using RemoteAdmin;
14 |
15 | namespace CedMod.Addons.QuerySystem.Patches
16 | {
17 | #if EXILED
18 | [HarmonyPatch(typeof(Permissions), nameof(Permissions.CheckPermission), typeof(CommandSender), typeof(string))]
19 | public static class ExiledPermissionsPatch
20 | {
21 | public static bool Prefix(ref bool __result, CommandSender sender, string permission)
22 | {
23 | if (!sender.FullPermissions)
24 | {
25 | if (CedModMain.Singleton.Config.QuerySystem.Debug)
26 | Logger.Info($"Exiled perms: {sender.GetType().FullName}");
27 |
28 | switch (sender)
29 | {
30 | case ServerConsoleSender _:
31 | break;
32 | case PlayerCommandSender _:
33 | Player player = Player.Get(sender.SenderId);
34 | if (player == null)
35 | {
36 | __result = CheckPermission(sender.SenderId, permission);
37 | return false;
38 | }
39 | __result = player.ReferenceHub == ReferenceHub.HostHub || player.CheckPermission(permission);
40 | return false;
41 | case CmSender _:
42 | __result = CheckPermission(sender.SenderId, permission);
43 | return false;
44 | }
45 | }
46 |
47 | __result = true;
48 | return false;
49 | }
50 |
51 | public static bool CheckPermission(string userId, string permission)
52 | {
53 | if (CedModMain.Singleton.Config.QuerySystem.Debug)
54 | Logger.Info(userId);
55 | if (string.IsNullOrEmpty(permission))
56 | return false;
57 |
58 | string plyGroupKey = Player.Get(userId) != null ? Player.Get(userId).GroupName : ServerStatic.PermissionsHandler.Members.FirstOrDefault(g => g.Key == userId).Value;
59 | if (CedModMain.Singleton.Config.QuerySystem.Debug)
60 | Logger.Info(plyGroupKey);
61 |
62 | if (plyGroupKey is null || !Permissions.Groups.TryGetValue(plyGroupKey, out Group group))
63 | {
64 | group = Permissions.DefaultGroup;
65 | }
66 |
67 | if (CedModMain.Singleton.Config.QuerySystem.Debug)
68 | {
69 | foreach (var grp in Exiled.Permissions.Extensions.Permissions.Groups)
70 | {
71 | Logger.Info(grp.Key);
72 | }
73 | }
74 |
75 | if (group is null)
76 | {
77 | return false;
78 | }
79 |
80 | const char permSeparator = '.';
81 | const string allPerms = ".*";
82 |
83 | if (group.CombinedPermissions.Contains(allPerms) || group.CombinedPermissions.Contains("*"))
84 | return true;
85 |
86 | if (permission.Contains(permSeparator))
87 | {
88 | StringBuilder strBuilder = StringBuilderPool.Shared.Rent();
89 | string[] seraratedPermissions = permission.Split(permSeparator);
90 |
91 | bool Check(string source) => group.CombinedPermissions.Contains(source, StringComparison.OrdinalIgnoreCase);
92 |
93 | bool result = false;
94 | for (int z = 0; z < seraratedPermissions.Length; z++)
95 | {
96 | if (z != 0)
97 | {
98 | strBuilder.Length -= allPerms.Length;
99 | strBuilder.Append(permSeparator);
100 | }
101 |
102 | strBuilder.Append(seraratedPermissions[z]);
103 |
104 | if (z == seraratedPermissions.Length - 1)
105 | {
106 | result = Check(strBuilder.ToString());
107 | break;
108 | }
109 |
110 | strBuilder.Append(allPerms);
111 | if (Check(strBuilder.ToString()))
112 | {
113 | result = true;
114 | break;
115 | }
116 | }
117 |
118 | StringBuilderPool.Shared.Return(strBuilder);
119 | return result;
120 | }
121 |
122 | bool result2 = group.CombinedPermissions.Contains(permission, StringComparison.OrdinalIgnoreCase);
123 | return result2;
124 | }
125 | }
126 | #endif
127 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/ExiledPermissionsPatchPlayer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 | using Exiled.API.Extensions;
5 | using Exiled.API.Features;
6 | using Exiled.Permissions.Extensions;
7 | using Exiled.Permissions.Features;
8 | using HarmonyLib;
9 | using LabApi.Features.Console;
10 | using NorthwoodLib.Pools;
11 |
12 | namespace CedMod.Addons.QuerySystem.Patches
13 | {
14 | #if EXILED
15 | [HarmonyPatch(typeof(Permissions), nameof(Permissions.CheckPermission), typeof(Player), typeof(string))]
16 | public static class ExiledPermissionsPatchPlayer
17 | {
18 | public static bool Prefix(ref bool __result, Player player, string permission)
19 | {
20 | if (string.IsNullOrEmpty(permission))
21 | {
22 | __result = false;
23 | return false;
24 | }
25 |
26 | if (Server.Host == player)
27 | {
28 | __result = true;
29 | return false;
30 | }
31 |
32 | if (player is null || player.GameObject is null || Permissions.Groups is null || Permissions.Groups.Count == 0)
33 | {
34 | __result = false;
35 | return false;
36 | }
37 |
38 | Logger.Debug($"UserID: {player.UserId} | PlayerId: {player.Id}", Exiled.Permissions.Permissions.Instance.Config.ShouldDebugBeShown);
39 | Logger.Debug($"Permission string: {permission}", Exiled.Permissions.Permissions.Instance.Config.ShouldDebugBeShown);
40 |
41 | string plyGroupKey = player.Group is not null ? (string.IsNullOrEmpty(player.GroupName) ? ServerStatic.PermissionsHandler.Groups.FirstOrDefault(g => g.Value.EqualsTo(player.Group)).Key : ServerStatic.PermissionsHandler.Groups.FirstOrDefault(g => g.Key == player.GroupName).Key) : null;
42 | Logger.Debug($"GroupKey: {plyGroupKey ?? "(null)"}", Exiled.Permissions.Permissions.Instance.Config.ShouldDebugBeShown);
43 |
44 | if (plyGroupKey is null || !Permissions.Groups.TryGetValue(plyGroupKey, out Group group))
45 | {
46 | Logger.Debug("The source group is null, the default group is used", Exiled.Permissions.Permissions.Instance.Config.ShouldDebugBeShown);
47 | group = Permissions.DefaultGroup;
48 | }
49 |
50 | if (group is null)
51 | {
52 | Logger.Debug("There's no default group, returning false...", Exiled.Permissions.Permissions.Instance.Config.ShouldDebugBeShown);
53 |
54 | __result = false;
55 | return false;
56 | }
57 |
58 | const char permSeparator = '.';
59 | const string allPerms = ".*";
60 |
61 | if (group.CombinedPermissions.Contains(allPerms) || group.CombinedPermissions.Contains("*"))
62 | {
63 | __result = true;
64 | return false;
65 | }
66 |
67 | if (permission.Contains(permSeparator))
68 | {
69 | StringBuilder strBuilder = StringBuilderPool.Shared.Rent();
70 | string[] seraratedPermissions = permission.Split(permSeparator);
71 |
72 | bool Check(string source) => group.CombinedPermissions.Contains(source, StringComparison.OrdinalIgnoreCase);
73 |
74 | bool result = false;
75 | for (int z = 0; z < seraratedPermissions.Length; z++)
76 | {
77 | if (z != 0)
78 | {
79 | // We need to clear the last ALL_PERMS line
80 | // or it'll be like 'permission.*.subpermission'.
81 | strBuilder.Length -= allPerms.Length;
82 |
83 | // Separate permission groups by using its separator.
84 | strBuilder.Append(permSeparator);
85 | }
86 |
87 | strBuilder.Append(seraratedPermissions[z]);
88 |
89 | // If it's the last index,
90 | // then we don't need to check for all permissions of the subpermission.
91 | if (z == seraratedPermissions.Length - 1)
92 | {
93 | result = Check(strBuilder.ToString());
94 | break;
95 | }
96 |
97 | strBuilder.Append(allPerms);
98 | if (Check(strBuilder.ToString()))
99 | {
100 | result = true;
101 | break;
102 | }
103 | }
104 |
105 | StringBuilderPool.Shared.Return(strBuilder);
106 |
107 | Logger.Debug($"Result in the block: {result}", Exiled.Permissions.Permissions.Instance.Config.ShouldDebugBeShown);
108 | __result = result;
109 | return false;
110 | }
111 |
112 | // It'll work when there is no dot in the permission.
113 | bool result2 = group.CombinedPermissions.Contains(permission, StringComparison.OrdinalIgnoreCase);
114 | Logger.Debug($"Result outside the block: {result2}", Exiled.Permissions.Permissions.Instance.Config.ShouldDebugBeShown);
115 | __result = result2;
116 | return false;
117 | }
118 | }
119 | #endif
120 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/PreAuthModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using LiteNetLib.Utils;
4 |
5 | namespace SlProxy
6 | {
7 | public class PreAuthModel
8 | {
9 | public NetDataWriter RawPreAuth;
10 | public bool IsChallenge { get; set; }
11 | public static PreAuthModel ReadPreAuth(NetDataReader reader)
12 | {
13 | try
14 | {
15 | PreAuthModel model = new PreAuthModel();
16 | model.RawPreAuth = NetDataWriter.FromBytes(reader.RawData, reader.UserDataOffset, reader.UserDataSize);
17 |
18 | if (reader.TryGetByte(out byte b))
19 | model.b = b;
20 | byte cBackwardRevision = 0;
21 | byte cMajor;
22 | byte cMinor;
23 | byte cRevision;
24 | bool cflag;
25 | if (!reader.TryGetByte(out cMajor) || !reader.TryGetByte(out cMinor) || !reader.TryGetByte(out cRevision) || !reader.TryGetBool(out cflag) || (cflag && !reader.TryGetByte(out cBackwardRevision)))
26 | {
27 | return null;
28 | }
29 |
30 | model.Major = cMajor;
31 | model.Minor = cMinor;
32 | model.Revision = cRevision;
33 | model.BackwardRevision = cBackwardRevision;
34 | model.flag = cflag;
35 |
36 | if (reader.TryGetInt(out int challengeid))
37 | {
38 | model.IsChallenge = challengeid != 0;
39 | model.ChallengeID = challengeid;
40 | }
41 | if (model.IsChallenge && reader.TryGetBytesWithLength(out byte[] challenge))
42 | model.Challenge = challenge;
43 | else
44 | model.Challenge = new byte[0];
45 | if (reader.TryGetString(out string userid))
46 | model.UserID = userid;
47 | if (reader.TryGetLong(out long expiration))
48 | model.Expiration = expiration;
49 | if (reader.TryGetByte(out byte flags))
50 | model.Flags = flags;
51 | if (reader.TryGetString(out string region))
52 | model.Region = region;
53 | if (reader.TryGetBytesWithLength(out byte[] signature))
54 | model.Signature = signature;
55 | Console.WriteLine(model);
56 | return model;
57 | }
58 | catch (Exception e)
59 | {
60 | //Logger.Error(e.ToString());
61 | }
62 |
63 | return null;
64 | }
65 |
66 | public byte b { get; set; }
67 | public byte Major { get; set; }
68 | public byte Minor { get; set; }
69 | public byte Revision { get; set; }
70 | public byte BackwardRevision { get; set; } = 0;
71 | public bool flag { get; set; }
72 | public int ChallengeID { get; set; }
73 | public byte[] Challenge { get; set; }
74 | public string UserID { get; set; } = "Unknown UserID";
75 | public long Expiration { get; set; }
76 | public byte Flags { get; set; }
77 | public string Region { get; set; } = "Unknown Region";
78 | public byte[] Signature { get; set; } = new byte[0];
79 | public override string ToString()
80 | {
81 | return string.Concat(
82 | $"Version: {Major}.{Minor}.{Revision}, Backward revision: {BackwardRevision}",
83 | Environment.NewLine,
84 | $"Challenge ID: {ChallengeID}",
85 | Environment.NewLine,
86 | $"Challenge: {Encoding.Default.GetString(Challenge)}",
87 | Environment.NewLine,
88 | $"UserID: {UserID}",
89 | Environment.NewLine,
90 | $"Expiration: {Expiration}",
91 | Environment.NewLine,
92 | $"Flags: {Flags}",
93 | Environment.NewLine,
94 | $"Region: {Region}",
95 | Environment.NewLine,
96 | $"Signature length: {Signature.Length}",
97 | Environment.NewLine,
98 | $"Signature: {Encoding.Default.GetString(Signature)}",
99 | Environment.NewLine,
100 | $"IsChallenge: {IsChallenge}");
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/RefreshExiledPermissions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using CedMod.Addons.QuerySystem.WS;
5 | using HarmonyLib;
6 | using LabApi.Features.Console;
7 |
8 | namespace CedMod.Addons.QuerySystem.Patches
9 | {
10 | #if EXILED
11 | [HarmonyPatch(typeof(Exiled.Permissions.Extensions.Permissions), nameof(Exiled.Permissions.Extensions.Permissions.Reload))]
12 | public static class RefreshExiledPermissions
13 | {
14 | public static bool Prefix()
15 | {
16 | if (!WebSocketSystem.UseRa)
17 | {
18 | Task.Run(() =>
19 | {
20 | try
21 | {
22 | WebSocketSystem.ApplyRa(true);
23 | }
24 | catch (Exception e)
25 | {
26 | Console.WriteLine(e);
27 | Logger.Error(e.ToString());
28 | }
29 | });
30 | return false;
31 | }
32 |
33 | return true;
34 | }
35 | }
36 | #endif
37 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/RefreshPermissionsHandlerPatch.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using CedMod.Addons.QuerySystem.WS;
3 | using HarmonyLib;
4 | using MEC;
5 |
6 | namespace CedMod.Addons.QuerySystem.Patches
7 | {
8 | [HarmonyPatch(typeof(PermissionsHandler), nameof(PermissionsHandler.RefreshPermissions))]
9 | public static class RefreshPermissionsHandlerPatch
10 | {
11 | public static bool Prefix()
12 | {
13 | if (!WebSocketSystem.UseRa)
14 | {
15 | new Thread(() => { WebSocketSystem.ApplyRa(true); }).Start();
16 | return false;
17 | }
18 |
19 | return true;
20 | }
21 | }
22 |
23 | [HarmonyPatch(typeof(ServerConfigSynchronizer), nameof(ServerConfigSynchronizer.RefreshRAConfigs))]
24 | public static class RefreshRaConfigsPatch
25 | {
26 | public static CoroutineHandle CoroutineHandle;
27 | public static bool Prefix()
28 | {
29 | if (CoroutineHandle.IsRunning)
30 | return false;
31 |
32 | CoroutineHandle = Timing.RunCoroutine(CedModMain.Singleton.QueryServerEvents.SyncStart(false));
33 |
34 | return true;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/Patches/ShootingPatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using CedMod.Addons.QuerySystem.WS;
6 | using HarmonyLib;
7 | using InventorySystem.Items.Firearms;
8 | using InventorySystem.Items.Firearms.Modules;
9 | using InventorySystem.Items.Firearms.Modules.Misc;
10 | using LabApi.Features.Wrappers;
11 | using Mirror;
12 | using PlayerRoles;
13 | using PlayerRoles.FirstPersonControl;
14 | using RelativePositioning;
15 | using UnityEngine;
16 |
17 | namespace CedMod.Addons.QuerySystem.Patches
18 | {
19 | [HarmonyPatch(typeof(HitscanHitregModuleBase), nameof(HitscanHitregModuleBase.ServerAppendPrescan))]
20 | public static class DoubleActionShootPatch
21 | {
22 | public static void Postfix(HitscanHitregModuleBase __instance, Ray targetRay, HitscanResult toAppend)
23 | {
24 | try
25 | {
26 | var player = __instance.Owner;
27 | if (player != null && player.roleManager != null && player.roleManager.CurrentRole is IFpcRole role)
28 | {
29 | var horLook = role.FpcModule.MouseLook.CurrentHorizontal;
30 | var verLook = role.FpcModule.MouseLook.CurrentVertical;
31 | var shotDirection = targetRay.direction.normalized;
32 | Quaternion lookRotation = Quaternion.Euler(-verLook, horLook, 0);
33 | Vector3 lookDirection = lookRotation * Vector3.forward;
34 |
35 | int targetId = -1;
36 | foreach (var destructible in toAppend.Destructibles)
37 | {
38 | if (destructible.Destructible is HitboxIdentity hitboxIdentity && !hitboxIdentity.TargetHub.IsAlive())
39 | {
40 | targetId = hitboxIdentity.TargetHub.PlayerId;
41 | }
42 | }
43 |
44 | float angle = Vector3.Angle(lookDirection, shotDirection);
45 |
46 | var plr = Player.Get(player);
47 | WebSocketSystem.Enqueue(new QueryCommand()
48 | {
49 | Recipient = "ALL",
50 | Data = new Dictionary()
51 | {
52 | {"ItemType", plr.CurrentItem.Type.ToString()},
53 | {"TargetPlayer", targetId.ToString()},
54 | {"UserId", plr.UserId},
55 | {"UserName", plr.Nickname},
56 | {"RayAngle", angle.ToString()},
57 | {"RayPos", targetRay.direction.ToString()},
58 | {"PlrPos", plr.Position.ToString()},
59 | {"plrRot", plr.Rotation.ToString()},
60 | {"Type", "OnPlayerShoot"},
61 | {
62 | "Message", string.Format(
63 | "{0} - {1} ({3}) has shot a {4}.", new object[]
64 | {
65 | plr.Nickname,
66 | plr.UserId,
67 | Misc.ToHex(player.roleManager.CurrentRole.RoleColor),
68 | plr.Role,
69 | plr.CurrentItem.Type
70 | })
71 | }
72 | }
73 | });
74 | }
75 | }
76 | catch (Exception e)
77 | {
78 | LabApi.Features.Console.Logger.Error(e.ToString());
79 | }
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/PlayerList.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using RemoteAdmin;
3 |
4 | namespace CedMod.Addons.QuerySystem
5 | {
6 | public class CommandHandler
7 | {
8 | public static readonly Dictionary Synced = new Dictionary();
9 | public static bool CheckPermissions(CommandSender sender, string queryZero, PlayerPermissions perm, string replyScreen = "", bool reply = true)
10 | {
11 | if ((ServerStatic.IsDedicated && sender.FullPermissions) || PermissionsHandler.IsPermitted(sender.Permissions, perm))
12 | return true;
13 |
14 | if (reply)
15 | sender.RaReply(queryZero + "#You don't have permissions to execute this command.\nMissing permission: " + perm, false, true, replyScreen);
16 |
17 | return false;
18 | }
19 | public static bool IsPlayer(CommandSender sender, string queryZero, string replyScreen = "")
20 | {
21 | if (sender is PlayerCommandSender)
22 | return true;
23 |
24 | sender.RaReply(queryZero + "#This command can be executed only from the game level.", success: false, logToConsole: true, replyScreen);
25 | return false;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/QueryMapEvents.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using CedMod.Addons.QuerySystem.WS;
3 | using LabApi.Events.Arguments.ServerEvents;
4 | using LabApi.Events.Arguments.WarheadEvents;
5 | using LabApi.Events.CustomHandlers;
6 |
7 | namespace CedMod.Addons.QuerySystem
8 | {
9 | public class QueryMapEvents: CustomEventsHandler
10 | {
11 | public override void OnWarheadDetonated(WarheadDetonatedEventArgs ev)
12 | {
13 | WebSocketSystem.Enqueue(new QueryCommand()
14 | {
15 | Recipient = "ALL",
16 | Data = new Dictionary()
17 | {
18 | {"Type", nameof(OnWarheadDetonated)},
19 | {"Message", "Warhead has been detonated"}
20 | }
21 | });
22 | }
23 |
24 | public override void OnServerLczDecontaminationAnnounced(LczDecontaminationAnnouncedEventArgs ev)
25 | {
26 | WebSocketSystem.Enqueue(new QueryCommand()
27 | {
28 | Recipient = "ALL",
29 | Data = new Dictionary()
30 | {
31 | {"Type", nameof(OnServerLczDecontaminationAnnounced)},
32 | {"Message", $"Light containment decontamination stage {ev.Phase}."}
33 | }
34 | });
35 | }
36 |
37 | public override void OnWarheadStarted(WarheadStartedEventArgs ev)
38 | {
39 | WebSocketSystem.Enqueue(new QueryCommand()
40 | {
41 | Recipient = "ALL",
42 | Data = new Dictionary()
43 | {
44 | {"Type", nameof(OnWarheadStarted)},
45 | {
46 | "Message",
47 | string.Format("warhead has been started: {0} seconds", 0) //todo implement
48 | }
49 | }
50 | });
51 | }
52 |
53 | public override void OnWarheadStopped(WarheadStoppedEventArgs ev)
54 | {
55 | WebSocketSystem.Enqueue(new QueryCommand()
56 | {
57 | Recipient = "ALL",
58 | Data = new Dictionary()
59 | {
60 | {"Type", nameof(OnWarheadStopped)},
61 | {"Message", (ev.Player != null ? ev.Player.Nickname + " - " + ev.Player.UserId : "Server") + " has stopped the detonation."}
62 | }
63 | });
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/QuerySystem.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using LabApi.Features.Console;
4 |
5 | namespace CedMod.Addons.QuerySystem
6 | {
7 | public class QuerySystem
8 | {
9 | public static List ReservedSlotUserids = new List();
10 | private static string _querySystemKey;
11 |
12 | public static string QuerySystemKey
13 | {
14 | get
15 | {
16 | if (string.IsNullOrEmpty(_querySystemKey))
17 | {
18 | if (!Directory.Exists(Path.Combine(CedModMain.PluginConfigFolder, "CedMod")))
19 | {
20 | Directory.CreateDirectory(Path.Combine(CedModMain.PluginConfigFolder, "CedMod"));
21 | }
22 | if (File.Exists(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", "QuerySystemSecretKey.txt")))
23 | {
24 | File.WriteAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"QuerySystemSecretKey-{ServerStatic.ServerPort}.txt"), File.ReadAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", "QuerySystemSecretKey.txt")));
25 | File.Delete(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", "QuerySystemSecretKey.txt"));
26 | }
27 |
28 | if (!File.Exists(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"QuerySystemSecretKey-{ServerStatic.ServerPort}.txt")))
29 | {
30 | return "";
31 | }
32 | _querySystemKey = File.ReadAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"QuerySystemSecretKey-{ServerStatic.ServerPort}.txt"));
33 |
34 | if (_querySystemKey == "")
35 | {
36 | return "";
37 | }
38 |
39 | Logger.Info("Read QueryKey from persistant storage");
40 | }
41 | return _querySystemKey;
42 | }
43 | set
44 | {
45 | if (!Directory.Exists(Path.Combine(CedModMain.PluginConfigFolder, "CedMod")))
46 | {
47 | Directory.CreateDirectory(Path.Combine(CedModMain.PluginConfigFolder, "CedMod"));
48 | }
49 | if (File.Exists(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", "QuerySystemSecretKey.txt")))
50 | {
51 | File.WriteAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"QuerySystemSecretKey-{ServerStatic.ServerPort}.txt"), File.ReadAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", "QuerySystemSecretKey.txt")));
52 | File.Delete(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", "QuerySystemSecretKey.txt"));
53 | }
54 | Logger.Info("Saved QueryKey to persistant storage");
55 | _querySystemKey = value;
56 | File.WriteAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"QuerySystemSecretKey-{ServerStatic.ServerPort}.txt"), _querySystemKey);
57 | }
58 | }
59 |
60 | public static string CurrentPanel = "";
61 | public static string CurrentMaster = MainPanelUrl;
62 | public static string CurrentMasterQuery = "";
63 | public const string MainPanelUrl = "panelapi.cedmod.nl";
64 | public static string DevPanelUrl = "gameapi.dev.cedmod.nl";
65 | public static bool UseSSL = true;
66 | public static bool IsDev { get; set; }
67 | public static List Whitelist { get; set; } = new List();
68 | public static bool UseWhitelist = false;
69 | }
70 | }
--------------------------------------------------------------------------------
/CedMod/Addons/QuerySystem/ServerPreferences.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Net;
4 | using System.Net.Http;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using CedMod.ApiModals;
8 | using LabApi.Features.Console;
9 | using Newtonsoft.Json;
10 |
11 | namespace CedMod.Addons.QuerySystem
12 | {
13 | public class ServerPreferences
14 | {
15 | public static ServerPreferenceModel Prefs = null;
16 |
17 | public static async Task ResolvePreferences(bool loop = true)
18 | {
19 | if (string.IsNullOrEmpty(QuerySystem.QuerySystemKey) || CedModMain.CancellationToken.IsCancellationRequested)
20 | return;
21 |
22 | try
23 | {
24 | using (HttpClient client = new HttpClient())
25 | {
26 | client.DefaultRequestHeaders.Add("X-ServerIp", ServerConsole.Ip);
27 | await VerificationChallenge.AwaitVerification();
28 | if (CedModMain.Singleton.Config.CedMod.ShowDebug)
29 | Logger.Debug($"Getting Prefs.");
30 | var response = await client.GetAsync($"http{(QuerySystem.UseSSL ? "s" : "")}://" + QuerySystem.CurrentMaster + $"/ServerPreference/GetServerPreference/{QuerySystem.QuerySystemKey}");
31 | if (response.IsSuccessStatusCode)
32 | {
33 | var data = JsonConvert.DeserializeObject(
34 | await response.Content.ReadAsStringAsync());
35 | Prefs = data;
36 | File.WriteAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"ServerPrefs.json"), JsonConvert.SerializeObject(Prefs));
37 | }
38 | else
39 | {
40 | if (response.StatusCode == HttpStatusCode.PreconditionRequired)
41 | {
42 | VerificationChallenge.CompletedChallenge = false;
43 | VerificationChallenge.ChallengeStarted = false;
44 | }
45 | Logger.Error($"Failed to resolve server preferences, using file: {response.StatusCode} {await response.Content.ReadAsStringAsync()}");
46 | if (File.Exists(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"ServerPrefs.json"))) ;
47 | Prefs = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine(CedModMain.PluginConfigFolder, "CedMod", $"ServerPrefs.json")));
48 | if (loop)
49 | {
50 | await Task.Delay(1000, CedModMain.CancellationToken);
51 | await ResolvePreferences();
52 | }
53 | return;
54 | }
55 | }
56 | }
57 | catch (Exception e)
58 | {
59 | if (e is TaskCanceledException)
60 | return;
61 | Logger.Error($"Failed to resolve server preferences, using file: {e}");
62 | if (loop)
63 | {
64 | await Task.Delay(1000, CedModMain.CancellationToken);
65 | await ResolvePreferences();
66 | }
67 | return;
68 | }
69 |
70 | if (loop)
71 | {
72 | await WaitForSecond(60, CedModMain.CancellationToken, (o) => !Shutdown._quitting && CedModMain.Singleton.CacheHandler != null);
73 | await ResolvePreferences();
74 | }
75 | }
76 |
77 | public static async Task WaitForSecond(int i, CancellationToken token, Predicate