protected override bool ExecuteParent(ArraySegment <string> arguments, ICommandSender sender, out string response) { EventHandlers.LogCommandUsed((CommandSender)sender, EventHandlers.FormatArguments(arguments, 0)); if (!((CommandSender)sender).CheckPermission("at.kick")) { response = "You do not have permission to use this command"; return(false); } if (arguments.Count < 2) { response = "Usage: kick (player id / name) (reason)"; return(false); } GameObject Ply = Exiled.API.Features.Player.Get(arguments.At(0)).GameObject; if (Ply == null) { response = $"Player not found: {arguments.At(0)}"; return(false); } ServerConsole.Disconnect(Ply, EventHandlers.FormatArguments(arguments, 1)); response = $"Player {Exiled.API.Features.Player.Get(arguments.At(0)).Nickname} has been kicked for \"{EventHandlers.FormatArguments(arguments, 1)}\""; return(true); }
public async Task <bool> DoKick(KickingEventArgs ev) { string banned_user_id = ev.Target.UserId; Player adminHub = ev.Issuer; string adminId = "idk"; Log.Info("Kick DETECTED:"); Log.Info($"Banned ID: {banned_user_id}"); Log.Info($"Admin Name: {adminHub.Nickname}"); Log.Info($"Admin ID: {adminId}"); if (await WebTask.IssueKick(plugin.Config.APIKey, banned_user_id, ev.Target.Nickname, adminId, ev.Reason)) { Log.Info($"Successfully pushed kick for {banned_user_id} to the web API!"); SendClientToServer(ev.Target, 7796); // We can safely remove the ban since the web client will handle it from here. //BanHandler.RemoveBan(ev.Details.Id, ev.Type); return(true); } else { // Error out to requesting admin adminHub.Broadcast(15, $"ERROR while adding kick to web API for: {ev.Target.Nickname}({banned_user_id})"); Log.Error($"FATAL KICKING ERROR! WebTask.IssueKick() Failed to push to web API"); ServerConsole.Disconnect(ev.Target.GameObject.gameObject, ev.Reason); return(false); } }
private string KickCommand(string[] arg, JObject jObject) { if (arg.Count() < 4) { return($"```{arg[1]} [UserID] [Reason]```"); } else if (!arg[2].Contains('@')) { return("Invalid UserID given"); } string reason = string.Join(" ", arg.Skip(3)); GameObject go = PlayerManager.players.Where(p => p.GetComponent <CharacterClassManager>().UserId == arg[2]).FirstOrDefault(); if (go == null || go.Equals(default(GameObject))) { return($"Unable to find user `{arg[2]}` on the server!"); } else { ServerConsole.Disconnect(go, reason); return($"`{go.GetComponent<NicknameSync>().MyNick} ({go.GetComponent<CharacterClassManager>().UserId})` was kicked with reason {reason}!"); } }
// Token: 0x06000005 RID: 5 RVA: 0x0000233C File Offset: 0x0000053C private static void HandlePlayerJoin(JoinedEventArgs ev) { State.AfkTime[ev.Player.ReferenceHub] = 0; State.PrevPos[ev.Player.ReferenceHub] = Vector3.zero; if (!ev.Player.ReferenceHub.serverRoles.Staff && SameThings.NicknameFilter.Any((string s) => ev.Player.Nickname.Contains(s))) { ServerConsole.Disconnect(ev.Player.GameObject, SameThings.NicknameFilterReason); } }
public IEnumerator <float> CheckVPN(PreAuthenticatingEventArgs ev) { IPAddress address = ev.Request.RemoteEndPoint.Address; if (IsWhiteListed(address) || IsBlackListed(address)) { Log.Debug($"[VPNChecker] Already Checked:{address}", SanyaPlugin.Instance.Config.IsDebugged); yield break; } using (UnityWebRequest unityWebRequest = UnityWebRequest.Get($"https://v2.api.iphub.info/ip/{address}")) { unityWebRequest.SetRequestHeader("X-Key", SanyaPlugin.Instance.Config.KickVpnApikey); yield return(Timing.WaitUntilDone(unityWebRequest.SendWebRequest())); if (!unityWebRequest.isNetworkError) { var data = JsonSerializer.Deserialize <VPNData>(unityWebRequest.downloadHandler.text); Log.Info($"[VPNChecker] Checking:{address}:{ev.UserId} ({data.countryCode}/{data.isp})"); if (data.block == 0 || data.block == 2) { Log.Info($"[VPNChecker] Passed:{address} UserId:{ev.UserId}"); AddWhiteList(address); yield break; } else if (data.block == 1) { Log.Warn($"[VPNChecker] VPN Detected:{address} UserId:{ev.UserId}"); AddBlackList(address); var player = Player.Get(ev.UserId); if (player != null) { ServerConsole.Disconnect(player.Connection, SanyaPlugin.Instance.Translation.VpnKickMessage); } if (!EventHandlers.kickedbyChecker.ContainsKey(ev.UserId)) { EventHandlers.kickedbyChecker.Add(ev.UserId, "vpn"); } yield break; } else { Log.Error($"[VPNChecker] Error({unityWebRequest.responseCode}):block == {data.block}"); } } else { Log.Error($"[VPNChecker] Error({unityWebRequest.responseCode}):{unityWebRequest.error}"); yield break; } } }
public void playerBan(PlayerBanEvent ev) { ev.Allow = false; GameObject player = ev.BannedPlayer.characterClassManager.gameObject; if (ev.Duration == 0) { ServerConsole.Disconnect(player, ev.FullMessage); } else { ServerConsole.Disconnect(player, ev.FullMessage); Ban BanJSON = new Ban(); BanJSON.Steamid64 = ev.BannedPlayer.characterClassManager.UserId; BanJSON.Ip = ev.BannedPlayer.queryProcessor._ipAddress; BanJSON.BannedAt = TimeBehaviour.CurrentTimestamp(); BanJSON.BannedUntil = DateTime.UtcNow.AddMinutes((double)ev.Duration).Ticks; BanJSON.By = ev.Issuer.characterClassManager.UserId; if (!String.IsNullOrEmpty(ev.Reason)) { BanJSON.Reason = ev.Reason; } String JSON = Serialize.ToJson(BanJSON); String JsonResponse = Methods.Post(Plugin.BanURL, JSON); try { JSON.Success.SuccessResponseJSON json = SanctionSystem.JSON.Success.SuccessResponseJSON.FromJson(JsonResponse); } catch (Exception e) { JSON.Error.ErrorResponseJSON json = SanctionSystem.JSON.Error.ErrorResponseJSON.FromJson(JsonResponse); if (!String.IsNullOrEmpty(json.Code)) { Log.Error("Erreur durant le processus d'API (Code d'erreur répondu par l'API: " + json.Code); } else { Log.Error("Erreur durant le processus d'API (Code d'erreur plugin: " + e); } } } }
public void OnPlayerVerfied(VerifiedEventArgs ev) { Timing.CallDelayed(1f, () => { foreach (string phrase in NameFilter.instance.Config.Badwords) { string name = ev.Player.Nickname.ToLower(); if (name.Contains(phrase)) { ServerConsole.Disconnect(ev.Player.GameObject, $"<color=\"cyan\">Detected inappropriate phrase ({phrase}) in your username. Please change it before joining the server.\nIf you believe this was a mistake, contact a staff member in our discord: https://discord.gg/XUtkhUp</color>"); } } foreach (string phrase in NameFilter.instance.Config.Advertising) { string name = ev.Player.Nickname.ToLower(); if (name.Contains(phrase)) { ServerConsole.Disconnect(ev.Player.GameObject, $"<color=\"cyan\">Detected advertising ({phrase}) in your username. Please change it before joining the server.\nIf you believe this was a mistake, contact a staff member in our discord: https://discord.gg/XUtkhUp</color>"); } } }); }
// Called every 1 second according to the player's Update function. This is way more efficient than the old way of doing a forloop for every player. // Also, since the gameObject for the player is deleted when they disconnect, we don't need to worry about cleaning any variables :) private void AFKChecker() { //Log.Info($"AFK Time: {this.AFKTime} AFK Count: {this.AFKCount}"); if (this.ply.Team == Team.RIP || Player.List.Count() <= plugin.Config.MinPlayers || (plugin.Config.IgnoreTut && this.ply.Team == Team.TUT)) { return; } bool isScp079 = (this.ply.Role == RoleType.Scp079) ? true : false; bool scp096TryNotToCry = false; // When SCP096 is in the state "TryNotToCry" he cannot move or it will cancel, // therefore, we don't want to AFK check 096 while he's in this state. if (this.ply.Role == RoleType.Scp096) { PlayableScps.Scp096 scp096 = this.ply.ReferenceHub.scpsController.CurrentScp as PlayableScps.Scp096; scp096TryNotToCry = (scp096.PlayerState == Scp096PlayerState.TryNotToCry) ? true : false; } Vector3 CurrentPos = this.ply.Position; Vector3 CurrentAngle = (isScp079) ? this.ply.Camera.targetPosition.position : this.ply.Rotation; if (CurrentPos != this.AFKLastPosition || CurrentAngle != this.AFKLastAngle || scp096TryNotToCry) { this.AFKLastPosition = CurrentPos; this.AFKLastAngle = CurrentAngle; this.AFKTime = 0; PlayerToReplace = null; return; } // The player hasn't moved past this point. this.AFKTime++; // If the player hasn't reached the time yet don't continue. if (this.AFKTime < plugin.Config.AfkTime) { return; } // Check if we're still in the "grace" period int secondsuntilspec = (plugin.Config.AfkTime + plugin.Config.GraceTime) - this.AFKTime; if (secondsuntilspec > 0) { string warning = plugin.Config.MsgGrace; warning = warning.Replace("%timeleft%", secondsuntilspec.ToString()); this.ply.ClearBroadcasts(); this.ply.Broadcast(1, $"{plugin.Config.MsgPrefix} {warning}"); return; } // The player is AFK and action will be taken. Log.Info($"{this.ply.Nickname} ({this.ply.UserId}) was detected as AFK!"); this.AFKTime = 0; // Let's make sure they are still alive before doing any replacement. if (this.ply.Team == Team.RIP) { return; } if (plugin.Config.TryReplace && !IsPastReplaceTime()) { Assembly easyEvents = Loader.Plugins.FirstOrDefault(pl => pl.Name == "EasyEvents")?.Assembly; var roleEasyEvents = easyEvents?.GetType("EasyEvents.Util")?.GetMethod("GetRole")?.Invoke(null, new object[] { this.ply }); // SCP035 Support (Credit DCReplace) bool is035 = false; try { is035 = this.ply.Id == TryGet035()?.Id; } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } // Credit: DCReplace :) // I mean at this point 90% of this has been rewritten lol... var inventory = this.ply.Inventory.items.Select(x => x.id).ToList(); RoleType role = this.ply.Role; Vector3 pos = this.ply.Position; float health = this.ply.Health; // New strange ammo system because the old one was f****d. uint ammo1 = this.ply.Ammo[(int)AmmoType.Nato556]; uint ammo2 = this.ply.Ammo[(int)AmmoType.Nato762]; uint ammo3 = this.ply.Ammo[(int)AmmoType.Nato9]; // Stuff for 079 byte Level079 = 0; float Exp079 = 0f, AP079 = 0f; if (isScp079) { Level079 = this.ply.Level; Exp079 = this.ply.Experience; AP079 = this.ply.Energy; } PlayerToReplace = Player.List.FirstOrDefault(x => x.Role == RoleType.Spectator && x.UserId != string.Empty && !x.IsOverwatchEnabled && x != this.ply); if (PlayerToReplace != null) { // Make the player a spectator first so other plugins can do things on player changing role with uAFK. this.ply.Inventory.Clear(); // Clear their items to prevent dupes. this.ply.SetRole(RoleType.Spectator); this.ply.Broadcast(30, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgFspec}"); PlayerToReplace.SetRole(role); Timing.CallDelayed(0.3f, () => { if (is035) { try { TrySpawn035(PlayerToReplace); } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } } PlayerToReplace.Position = pos; PlayerToReplace.ClearInventory(); PlayerToReplace.ResetInventory(inventory); PlayerToReplace.Health = health; PlayerToReplace.Ammo[(int)AmmoType.Nato556] = ammo1; PlayerToReplace.Ammo[(int)AmmoType.Nato762] = ammo2; PlayerToReplace.Ammo[(int)AmmoType.Nato9] = ammo3; if (isScp079) { PlayerToReplace.Level = Level079; PlayerToReplace.Experience = Exp079; PlayerToReplace.Energy = AP079; } PlayerToReplace.Broadcast(10, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgReplace}"); if (roleEasyEvents != null) { easyEvents?.GetType("EasyEvents.CustomRoles")?.GetMethod("ChangeRole")?.Invoke(null, new object[] { PlayerToReplace, roleEasyEvents }); } PlayerToReplace = null; }); } else { // Couldn't find a valid player to spawn, just ForceToSpec anyways. ForceToSpec(this.ply); } } else { // Replacing is disabled, just ForceToSpec ForceToSpec(this.ply); } // If it's -1 we won't be kicking at all. if (plugin.Config.NumBeforeKick != -1) { // Increment AFK Count this.AFKCount++; if (this.AFKCount >= plugin.Config.NumBeforeKick) { // Since this.AFKCount is greater than the config we're going to kick that player for being AFK too many times in one match. ServerConsole.Disconnect(this.gameObject, plugin.Config.MsgKick); } } }
private static bool Prefix(GameObject user, int duration, string reason, string issuer, bool isGlobalBan) { try { if (isGlobalBan && ConfigFile.ServerConfig.GetBool("gban_ban_ip", false)) { duration = int.MaxValue; } string userId = null; string address = user.GetComponent <NetworkIdentity>().connectionToClient.address; API.Features.Player targetPlayer = API.Features.Player.Get(user); API.Features.Player issuerPlayer = API.Features.Player.Get(issuer) ?? API.Features.Server.Host; try { if (ConfigFile.ServerConfig.GetBool("online_mode", false)) { userId = targetPlayer.UserId; } } catch { ServerConsole.AddLog("Failed during issue of User ID ban (1)!"); return(false); } string message = $"You have been {((duration > 0) ? "banned" : "kicked")}. "; if (!string.IsNullOrEmpty(reason)) { message = message + "Reason: " + reason; } if (!ServerStatic.PermissionsHandler.IsVerified || !targetPlayer.IsStaffBypassEnabled) { if (duration > 0) { var ev = new BanningEventArgs(targetPlayer, issuerPlayer, duration, reason, message); Player.OnBanning(ev); duration = ev.Duration; reason = ev.Reason; message = ev.FullMessage; if (!ev.IsAllowed) { return(false); } string originalName = string.IsNullOrEmpty(targetPlayer.Nickname) ? "(no nick)" : targetPlayer.Nickname; long issuanceTime = TimeBehaviour.CurrentTimestamp(); long banExpieryTime = TimeBehaviour.GetBanExpirationTime((uint)duration); try { if (userId != null && !isGlobalBan) { BanHandler.IssueBan( new BanDetails { OriginalName = originalName, Id = userId, IssuanceTime = issuanceTime, Expires = banExpieryTime, Reason = reason, Issuer = issuer, }, BanHandler.BanType.UserId); if (!string.IsNullOrEmpty(targetPlayer.CustomUserId)) { BanHandler.IssueBan( new BanDetails { OriginalName = originalName, Id = targetPlayer.CustomUserId, IssuanceTime = issuanceTime, Expires = banExpieryTime, Reason = reason, Issuer = issuer, }, BanHandler.BanType.UserId); } } } catch { ServerConsole.AddLog("Failed during issue of User ID ban (2)!"); return(false); } try { if (ConfigFile.ServerConfig.GetBool("ip_banning", false) || isGlobalBan) { BanHandler.IssueBan( new BanDetails { OriginalName = originalName, Id = address, IssuanceTime = issuanceTime, Expires = banExpieryTime, Reason = reason, Issuer = issuer, }, BanHandler.BanType.IP); } } catch { ServerConsole.AddLog("Failed during issue of IP ban!"); return(false); } } else if (duration == 0) { var ev = new KickingEventArgs(targetPlayer, issuerPlayer, reason, message); Player.OnKicking(ev); reason = ev.Reason; message = ev.FullMessage; if (!ev.IsAllowed) { return(false); } } } ServerConsole.Disconnect(targetPlayer.ReferenceHub.gameObject, message); return(false); } catch (Exception e) { Exiled.API.Features.Log.Error($"Exiled.Events.Patches.Events.Player.BanningAndKicking: {e}\n{e.StackTrace}"); return(true); } }
public static void HandleCommand(JObject o) { try { string type = (string)o["type"]; if (type == "IDENT") { if ((string)o["data"] == "PASS") { Log.Debug($"Server {ServerConsole.Port} passed identification."); } else if ((string)o["data"] == "FAIL") { Log.Warn($"Server {ServerConsole.Port} failed identification."); } } else if (type == "UPDATE") { EventHandlers.tcp.SendData(new Update()); } else if (type == "ROLESYNC") { Log.Warn(o); string userid = (string)o["userid"]; if (o["group"] == null) { Log.Debug($"No role sync found for {userid}"); SCPDiscord.VerifyReservedSlot(userid); return; } string group = (string)o["group"]; UserGroup userGroup = ServerStatic.PermissionsHandler.GetGroup(group); if (userGroup == null) { Log.Error($"Attempted to assign invalid user group {group} to {userid}"); return; } Player player = Player.Get(userid); if (player == null) { Log.Error($"Error assigning user group to {userid}, player not found."); return; } if (SCPDiscord.setRoleGroups.Contains(group)) { Log.Debug($"Assigning role: {userGroup} to {userid}."); player.Group = userGroup; } string tag = (string)o["tag"]; if (SCPDiscord.setTagGroups.Contains(group) && tag != null) { Log.Debug($"Changing tag of {userid} to {tag}."); player.RankName = tag; } if (SCPDiscord.reservedSlotGroups.Contains(group)) { // grant reserved slot Log.Debug("Player has necessary rank for reserved slot, checking..."); List <string> lines = File.ReadAllLines(SCPDiscord.reservedSlots).ToList(); if (!lines.Contains(userid)) { Log.Debug("Reserved slot not found, adding player..."); lines.Add(userid); File.WriteAllLines(SCPDiscord.reservedSlots, lines); // This only reloads the slots on the current server, change this to reload on every server? // Might not work ReservedSlot.Reload(); } } else { SCPDiscord.VerifyReservedSlot(userid); } } else if (type == "COMMAND") { GameCore.Console.singleton.TypeCommand((string)o["command"]); } else if (type == "BAN") { bool isuid = false; string uid = (string)o["user"]; if (!uid.Contains("@steam") && !uid.Contains("@discord")) { if (!uid.Contains(".")) { isuid = true; uid += "@steam"; } } else { isuid = true; } Player player = Player.Get(uid); int min = (int)o["min"]; string reason = (string)o["reason"]; Ban ban = new Ban { player = null, duration = min, success = true, offline = false }; if (player != null) { PlayerManager.localPlayer.GetComponent <BanPlayer>().BanUser(player.GameObject, min, reason, "Server"); ban.player = new User { name = player.Nickname, userid = player.UserId }; } else { if (isuid) { ban.offline = true; ban.player = new User { name = "Offline Player", userid = uid }; if (SCPDiscord.instance.Config.SteamApiKey != string.Empty) { string data = null; try { data = webclient.DownloadString($"https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key={SCPDiscord.instance.Config.SteamApiKey}&format=json&steamids={uid.Replace("@steam", "")}"); } catch { Log.Debug("Failed to get profile data from SteamAPI."); } JObject o2 = JObject.Parse(data); if (o2 != null) { ban.player.name = (string)o2["response"]["players"][0]["personaname"]; } } BanHandler.IssueBan(new BanDetails() { OriginalName = ban.player.name, Id = uid, IssuanceTime = TimeBehaviour.CurrentTimestamp(), Expires = DateTime.UtcNow.AddMinutes((double)min).Ticks, Reason = reason, Issuer = "Server" }, BanHandler.BanType.UserId); } else if (uid.Contains(".")) { ban.offline = true; BanHandler.IssueBan(new BanDetails() { OriginalName = "IP Address", Id = uid, IssuanceTime = TimeBehaviour.CurrentTimestamp(), Expires = DateTime.UtcNow.AddMinutes((double)min).Ticks, Reason = reason, Issuer = "Server" }, BanHandler.BanType.IP); } else { ban.success = false; } } EventHandlers.tcp.SendData(ban); } else if (type == "KICK") { string uid = (string)o["user"]; if (!uid.Contains("@steam") && !uid.Contains("@discord")) { uid += "@steam"; } Player player = Player.Get(uid); Kick kick = new Kick { player = null }; if (player != null) { kick.player = new User { name = player.Nickname, userid = player.UserId }; ServerConsole.Disconnect(player.GameObject, (string)o["reason"]); } EventHandlers.tcp.SendData(kick); } else if (type == "UNBAN") { Unban unban = new Unban(); List <string> ipBans = File.ReadAllLines(SCPDiscord.ipBans).ToList(); List <string> userIDBans = File.ReadAllLines(SCPDiscord.useridBans).ToList(); string id = (string)o["user"]; if (!id.Contains(".")) { if (!id.Contains("@steam") && !id.Contains("@discord")) { id += "@steam"; } } List <string> matchingIPBans = ipBans.FindAll(s => s.Contains(id)); List <string> matchingSteamIDBans = userIDBans.FindAll(s => s.Contains(id)); if (matchingIPBans.Count == 0 && matchingSteamIDBans.Count == 0) { unban.success = false; EventHandlers.tcp.SendData(unban); return; } ipBans.RemoveAll(s => s.Contains(id)); userIDBans.RemoveAll(s => s.Contains(id)); foreach (var row in matchingIPBans) { userIDBans.RemoveAll(s => s.Contains(row.Split(';').Last())); } foreach (var row in matchingSteamIDBans) { ipBans.RemoveAll(s => s.Contains(row.Split(';').Last())); } File.WriteAllLines(SCPDiscord.ipBans, ipBans); File.WriteAllLines(SCPDiscord.useridBans, userIDBans); EventHandlers.tcp.SendData(unban); } } catch (Exception x) { Log.Error("SCPDiscord handle command error: " + x.Message); } }
private string BanCommand(string[] arg, JObject jObject) { try { if (arg.Count() < 5) { return($"```{arg[1]} [UserID/Ip] [Duration] [Reason]```"); } bool validUID = arg[2].Contains('@'); bool validIP = IPAddress.TryParse(arg[2], out IPAddress ip); if (!validIP && !validUID) { return($"```diff\n- Invalid UserID or IP given```"); } var chars = arg[3].Where(Char.IsLetter).ToArray(); //return string.Join(" ", chars); if (chars.Length < 1 || !int.TryParse(new string(arg[3].Where(Char.IsDigit).ToArray()), out int amount) || !validUnits.Contains(chars[0]) || amount < 1) { return("```diff\n- Invalid duration```"); } TimeSpan duration = GetBanDuration(chars[0], amount); string reason = string.Join(" ", arg.Skip(4)); ReferenceHub player = null; if (validIP) { var list = ReferenceHub.GetAllHubs().Where(p => p.Value.characterClassManager.connectionToClient.address == arg[2]); if (list.Count() > 0) { player = list.First().Value; } } else { var list = ReferenceHub.GetAllHubs().Where(p => p.Value.characterClassManager.UserId == arg[2]); if (list.Count() > 0) { player = list.First().Value; } } if (player != null) { BanHandler.IssueBan(new BanDetails { OriginalName = player.nicknameSync.MyNick, Id = player.characterClassManager.UserId, Issuer = jObject["Staff"].ToString(), IssuanceTime = DateTime.UtcNow.Ticks, Expires = DateTime.UtcNow.Add(duration).Ticks, Reason = reason }, BanHandler.BanType.UserId); BanHandler.IssueBan(new BanDetails { OriginalName = player.nicknameSync.MyNick, Id = player.characterClassManager.connectionToClient.address, Issuer = jObject["Staff"].ToString(), IssuanceTime = DateTime.UtcNow.Ticks, Expires = DateTime.UtcNow.Add(duration).Ticks, Reason = reason }, BanHandler.BanType.IP); ServerConsole.Disconnect(player.gameObject, reason); return($"`{player.nicknameSync.MyNick} ({player.characterClassManager.UserId})` was banned for {arg[3]} with reason: {reason}"); } else { BanHandler.IssueBan(new BanDetails { OriginalName = "Offline player", Id = arg[2], Issuer = jObject["Staff"].ToString(), IssuanceTime = DateTime.UtcNow.Ticks, Expires = DateTime.UtcNow.Add(duration).Ticks, Reason = reason }, (validUID ? BanHandler.BanType.UserId : BanHandler.BanType.IP)); return($"`{arg[2]}` was banned for {arg[3]} with reason {reason}!"); } } catch (Exception e) { return(e.ToString()); } }
private void OnPlayerInteract(PlayerInteractPacket packet, NetPeer peer) { PlayerInteractionType interactionType = (PlayerInteractionType)packet.Type; if (!InstalledAddons.TryGetValue(packet.AddonId, out AddonInfo addonInfo)) { Logger.Error($"Addon with id \"{packet.AddonId}\" tried to use interaction \"{interactionType}\" on player \"{packet.UserID}\" but addon is not loaded!"); return; } NetDataReader reader = new NetDataReader(packet.Data); Player p = (packet.UserID == "SERVER CONSOLE" || packet.UserID == "GAME CONSOLE") ? Player.Get(PlayerManager.localPlayer) : Player.Get(packet.UserID); if (p == null) { Logger.Info($"Player not found {packet.UserID}, action: {interactionType}."); return; } switch (interactionType) { // Kill player case PlayerInteractionType.KillPlayer: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.KillPlayer)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to \"{interactionType}\" but server dont have required permission!"); break; } p.Kill("Force"); break; // Report message case PlayerInteractionType.ReportMessage: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.ReportMessages)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to send \"{interactionType}\" but server dont have required permission!"); break; } p.SendConsoleMessage($"[REPORTING] {reader.GetString()}", "GREEN"); break; // Remoteadmin message case PlayerInteractionType.RemoteAdminMessage: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.RemoteAdminMessages)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to send \"{interactionType}\" but server dont have required permission!"); break; } p.RemoteAdminMessage(reader.GetString(), true, reader.GetString()); break; // Console message case PlayerInteractionType.GameConsoleMessage: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.GameConsoleMessages)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to send \"{interactionType}\" but server dont have required permission!"); break; } var message = reader.GetString(); var pluginName = reader.GetString(); p.SendConsoleMessage($"{(!string.IsNullOrEmpty(pluginName) ? $"[{pluginName}] " : string.Empty)}{message}", reader.GetString()); break; // Redirect case PlayerInteractionType.Redirect: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.RedirectPlayer)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to \"{interactionType}\" player but server dont have required permission!"); break; } SendClientToServer(p, reader.GetUShort()); break; // Disconnect case PlayerInteractionType.Disconnect: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.DisconnectPlayer)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to \"{interactionType}\" player but server dont have required permission!"); break; } ServerConsole.Disconnect(p.GameObject, reader.GetString()); break; // Hint case PlayerInteractionType.Hint: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.HintMessages)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to send \"{interactionType}\" player but server dont have required permission!"); break; } p.ShowHint(reader.GetString(), reader.GetFloat()); break; // Send position to network case PlayerInteractionType.SendPosition: bool sendPosition = reader.GetBool(); if (!p.SessionVariables.ContainsKey("SP")) { p.SessionVariables.Add("SP", sendPosition); } p.SessionVariables["SP"] = sendPosition; break; // Send rotation to network case PlayerInteractionType.SendRotation: bool sendRotation = reader.GetBool(); if (!p.SessionVariables.ContainsKey("SR")) { p.SessionVariables.Add("SR", sendRotation); } p.SessionVariables["SR"] = sendRotation; break; // Teleport case PlayerInteractionType.Teleport: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.TeleportPlayer)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to \"{interactionType}\" player but server dont have required permission!"); break; } p.Position = new UnityEngine.Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); break; // Godmode case PlayerInteractionType.Godmode: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.GodmodePlayer)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to change \"{interactionType}\" player but server dont have required permission!"); break; } p.IsGodModeEnabled = reader.GetBool(); break; // Noclip case PlayerInteractionType.Noclip: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.NoclipPlayer)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to change \"{interactionType}\" player but server dont have required permission!"); break; } p.NoClipEnabled = reader.GetBool(); break; // Clear Inv case PlayerInteractionType.ClearInventory: if (!Extensions.CheckSendPermission(AddonReceivePermissionTypes.ClearInventoryPlayer)) { Logger.Error($"Addon \"{addonInfo.AddonName}\" tried to \"{interactionType}\" but server dont have required permission!"); break; } p.ClearInventory(); break; } }
public static bool Prefix(GameObject user, int duration, string reason, string issuer, bool isGlobalBan) { if (isGlobalBan && ConfigFile.ServerConfig.GetBool("gban_ban_ip", false)) { duration = int.MaxValue; } string userId = null; string address = user.GetComponent <NetworkIdentity>().connectionToClient.address; CharacterClassManager characterClassManager = null; ReferenceHub userHub = Extensions.Player.GetPlayer(user); try { if (ConfigFile.ServerConfig.GetBool("online_mode", false)) { characterClassManager = userHub.characterClassManager; userId = characterClassManager.UserId; } } catch { ServerConsole.AddLog("Failed during issue of User ID ban (1)!"); return(false); } string message = $"You have been {((duration > 0) ? "banned" : "kicked")}. "; if (!string.IsNullOrEmpty(reason)) { message = message + "Reason: " + reason; } try { bool allow = true; Events.InvokePlayerBan(ref userHub, ref userId, ref duration, ref allow, ref message, ref reason); if (!allow) { return(false); } } catch (Exception ex) { Log.Error($"Error in OnBanPlayer event: {ex.ToString()}"); } if (duration > 0 && (!ServerStatic.PermissionsHandler.IsVerified || !userHub.serverRoles.BypassStaff)) { string originalName = string.IsNullOrEmpty(userHub.nicknameSync.MyNick) ? "(no nick)" : userHub.nicknameSync.MyNick; long issuanceTime = TimeBehaviour.CurrentTimestamp(); long banExpieryTime = TimeBehaviour.GetBanExpieryTime((uint)duration); try { if (userId != null && !isGlobalBan) { BanHandler.IssueBan(new BanDetails { OriginalName = originalName, Id = userId, IssuanceTime = issuanceTime, Expires = banExpieryTime, Reason = reason, Issuer = issuer }, BanHandler.BanType.UserId); if (!string.IsNullOrEmpty(characterClassManager.UserId2)) { BanHandler.IssueBan(new BanDetails { OriginalName = originalName, Id = characterClassManager.UserId2, IssuanceTime = issuanceTime, Expires = banExpieryTime, Reason = reason, Issuer = issuer }, BanHandler.BanType.UserId); } } } catch { ServerConsole.AddLog("Failed during issue of User ID ban (2)!"); return(false); } try { if (ConfigFile.ServerConfig.GetBool("ip_banning", false) || isGlobalBan) { BanHandler.IssueBan(new BanDetails { OriginalName = originalName, Id = address, IssuanceTime = issuanceTime, Expires = banExpieryTime, Reason = reason, Issuer = issuer }, BanHandler.BanType.IP); } } catch { ServerConsole.AddLog("Failed during issue of IP ban!"); return(false); } } List <GameObject> playersToBan = new List <GameObject>(); foreach (GameObject gameObject in PlayerManager.players) { characterClassManager = gameObject.GetComponent <CharacterClassManager>(); if ((userId != null && characterClassManager.UserId == userId) || (address != null && characterClassManager.connectionToClient.address == address)) { playersToBan.Add(characterClassManager.gameObject); } } foreach (GameObject player in playersToBan) { ServerConsole.Disconnect(player, message); } return(false); }
// Called every 1 second according to the player's Update function. This is way more efficient than the old way of doing a forloop for every player. // Also, since the gameObject for the player is deleted when they disconnect, we don't need to worry about cleaning any variables :) private void AFKChecker() { //Log.Info($"AFK Time: {this.AFKTime} AFK Count: {this.AFKCount}"); if (this.ply.Team == Team.RIP) { return; } bool isScp079 = (this.ply.Role == RoleType.Scp079) ? true : false; bool scp096TryNotToCry = false; // When SCP096 is in the state "TryNotToCry" he cannot move or it will cancel, // therefore, we don't want to AFK check 096 while he's in this state. if (this.ply.Role == RoleType.Scp096) { PlayableScps.Scp096 scp096 = this.ply.ReferenceHub.scpsController.CurrentScp as PlayableScps.Scp096; scp096TryNotToCry = (scp096.PlayerState == Scp096PlayerState.TryNotToCry) ? true : false; } Vector3 CurrentPos = this.ply.Position; Vector3 CurrentAngle = (isScp079) ? this.ply.Camera.targetPosition.position : this.ply.Rotation; if (CurrentPos != this.AFKLastPosition || CurrentAngle != this.AFKLastAngle || scp096TryNotToCry) { this.AFKLastPosition = CurrentPos; this.AFKLastAngle = CurrentAngle; this.AFKTime = 0; return; } // The player hasn't moved past this point. this.AFKTime++; // If the player hasn't reached the time yet don't continue. if (this.AFKTime < plugin.Config.AfkTime) { return; } // Check if we're still in the "grace" period int secondsuntilspec = (plugin.Config.AfkTime + plugin.Config.GraceTime) - this.AFKTime; if (secondsuntilspec > 0) { string warning = plugin.Config.MsgGrace; warning = warning.Replace("%timeleft%", secondsuntilspec.ToString()); this.ply.ClearBroadcasts(); this.ply.Broadcast(1, $"{plugin.Config.MsgPrefix} {warning}"); return; } // The player is AFK and action will be taken. Log.Info($"{this.ply.Nickname} ({this.ply.UserId}) was detected as AFK!"); this.AFKTime = 0; // Let's make sure they are still alive before doing any replacement. if (this.ply.Team == Team.RIP) { return; } if (plugin.Config.TryReplace && !this.IsPastReplaceTime()) { var roleEasyEvents = Loader.Plugins.FirstOrDefault(pl => pl.Name == "EasyEvents")?.Assembly.GetType("EasyEvents.Util")?.GetMethod("GetRole")?.Invoke(null, new object[] { this.ply }); // SCP035 Support (Credit DCReplace) bool is035 = false; try { is035 = this.ply.Id == TryGet035()?.Id; } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } // Credit: DCReplace :) // I mean at this point 90% of this has been rewritten lol... Inventory.SyncListItemInfo items = this.ply.Inventory.items; RoleType role = this.ply.Role; Vector3 pos = this.ply.Position; float health = this.ply.Health; // New strange ammo system because the old one was f****d. Dictionary <Exiled.API.Enums.AmmoType, uint> ammo = new Dictionary <Exiled.API.Enums.AmmoType, uint>(); foreach (Exiled.API.Enums.AmmoType atype in (Exiled.API.Enums.AmmoType[])Enum.GetValues(typeof(Exiled.API.Enums.AmmoType))) { ammo.Add(atype, this.ply.Ammo[(int)atype]); this.ply.Ammo[(int)atype] = 0; // We remove the ammo so the player doesn't drop it (duplicate ammo) } // Stuff for 079 byte Level079 = 0; float Exp079 = 0f, AP079 = 0f; if (isScp079) { Level079 = this.ply.Level; Exp079 = this.ply.Experience; AP079 = this.ply.Energy; } Player player = Player.List.FirstOrDefault(x => x.Role == RoleType.Spectator && x.UserId != string.Empty && !x.IsOverwatchEnabled && x != this.ply); if (player != null) { player.SetRole(role); Timing.CallDelayed(0.3f, () => { if (is035) { try { TrySpawn035(player); } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } } player.Position = pos; player.Inventory.Clear(); foreach (Inventory.SyncItemInfo item in items) { player.Inventory.AddNewItem(item.id, item.durability, item.modSight, item.modBarrel, item.modOther); } player.Health = health; foreach (Exiled.API.Enums.AmmoType atype in (Exiled.API.Enums.AmmoType[])Enum.GetValues(typeof(Exiled.API.Enums.AmmoType))) { uint amount; if (ammo.TryGetValue(atype, out amount)) { this.ply.Ammo[(int)atype] = amount; } else { Log.Error($"[uAFK] ERROR: Tried to get a value from dict that did not exist! (Ammo)"); } } if (isScp079) { player.Level = Level079; player.Experience = Exp079; player.Energy = AP079; } player.Broadcast(10, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgReplace}"); if (roleEasyEvents != null) { Loader.Plugins.FirstOrDefault(pl => pl.Name == "EasyEvents")?.Assembly.GetType("EasyEvents.CustomRoles")?.GetMethod("ChangeRole")?.Invoke(null, new object[] { player, roleEasyEvents }); } this.ply.Inventory.Clear(); // Clear their items to prevent dupes. this.ply.SetRole(RoleType.Spectator); this.ply.Broadcast(30, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgFspec}"); }); } else { // Couldn't find a valid player to spawn, just ForceToSpec anyways. this.ForceToSpec(this.ply); } } else { // Replacing is disabled, just ForceToSpec this.ForceToSpec(this.ply); } // If it's -1 we won't be kicking at all. if (plugin.Config.NumBeforeKick != -1) { // Increment AFK Count this.AFKCount++; if (this.AFKCount >= plugin.Config.NumBeforeKick) { // Since AFKCount is greater than the config we're going to kick that player for being AFK too many times in one match. ServerConsole.Disconnect(this.gameObject, plugin.Config.MsgKick); } } }
public void Kick(string message) => ServerConsole.Disconnect(gameObject, message);
/// <summary> /// Disconnects a <see cref="ReferenceHub">player</see>. /// </summary> /// <param name="player"></param> public static void Disconnect(this ReferenceHub player, string reason = null) => ServerConsole.Disconnect(player.gameObject, string.IsNullOrEmpty(reason) ? "" : reason);
public IEnumerator <float> CheckSteam(string userid) { PlayerData data = null; if (SanyaPlugin.Instance.Config.DataEnabled && SanyaPlugin.Instance.PlayerDataManager.PlayerDataDict.TryGetValue(userid, out data) && (!SanyaPlugin.Instance.Config.KickSteamLimited || !data.steamlimited) && (!SanyaPlugin.Instance.Config.KickSteamVacBanned || !data.steamvacbanned)) { Log.Debug($"[SteamCheck] Already Checked:{userid}", SanyaPlugin.Instance.Config.IsDebugged); yield break; } string xmlurl = string.Concat( "https://steamcommunity.com/profiles/", userid.Replace("@steam", string.Empty), "?xml=1" ); using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(xmlurl)) { yield return(Timing.WaitUntilDone(unityWebRequest.SendWebRequest())); if (!unityWebRequest.isNetworkError) { XmlReaderSettings xmlReaderSettings = new XmlReaderSettings() { IgnoreComments = true, IgnoreWhitespace = true }; XmlReader xmlReader = XmlReader.Create(new MemoryStream(unityWebRequest.downloadHandler.data), xmlReaderSettings); bool ReadSuccess = false; while (xmlReader.Read()) { if (xmlReader.ReadToFollowing("vacBanned") && SanyaPlugin.Instance.Config.KickSteamVacBanned) { ReadSuccess = true; string isVacBanned = xmlReader.ReadElementContentAsString(); if (isVacBanned == "0") { Log.Info($"[SteamCheck:VacBanned] OK:{userid}"); if (data != null) { data.steamvacbanned = false; SanyaPlugin.Instance.PlayerDataManager.SavePlayerData(data); } } else { Log.Warn($"[SteamCheck:VacBanned] NG:{userid}"); var player = Player.Get(userid); if (player != null) { ServerConsole.Disconnect(player.Connection, SanyaPlugin.Instance.Translation.VacBannedKickMessage); } if (!EventHandlers.kickedbyChecker.ContainsKey(userid)) { EventHandlers.kickedbyChecker.Add(userid, "steam_vac"); } } } if (xmlReader.ReadToFollowing("isLimitedAccount") && SanyaPlugin.Instance.Config.KickSteamLimited) { ReadSuccess = true; string isLimited = xmlReader.ReadElementContentAsString(); if (isLimited == "0") { Log.Info($"[SteamCheck:Limited] OK:{userid}"); if (data != null) { data.steamlimited = false; SanyaPlugin.Instance.PlayerDataManager.SavePlayerData(data); } } else { Log.Warn($"[SteamCheck:Limited] NG:{userid}"); var player = Player.Get(userid); if (player != null) { ServerConsole.Disconnect(player.Connection, SanyaPlugin.Instance.Translation.LimitedKickMessage); } if (!EventHandlers.kickedbyChecker.ContainsKey(userid)) { EventHandlers.kickedbyChecker.Add(userid, "steam_limited"); } } } if (!ReadSuccess) { Log.Warn($"[SteamCheck] Falied(NoProfile or Error):{userid}"); var player = Player.Get(userid); if (player != null) { ServerConsole.Disconnect(player.Connection, SanyaPlugin.Instance.Translation.NoProfileKickMessage); } if (!EventHandlers.kickedbyChecker.ContainsKey(userid)) { EventHandlers.kickedbyChecker.Add(userid, "steam_noprofile"); } } yield break; } } else { Log.Error($"[SteamCheck] Failed(NetworkError):{userid}:{unityWebRequest.error}"); yield break; } } yield break; }