public PlayerApprovalEvent(ConnectionAcceptor ca, NetworkPlayerApproval approval, ClientConnection cc, bool AboutToDeny) { this._ca = ca; this._cc = cc; this._approval = approval; this._deny = AboutToDeny; }
public void Stop() { ConnectionAcceptor.Stop(); foreach (var session in this.Sessions.Values) { CloseSession(session); } }
public static void ConnectionAcceptor_OnPlayerApproval(ConnectionAcceptor hook, NetworkPlayerApproval approval) { object[] args = new object[] { hook, approval }; Method.Invoke("RustExtended.RustHook.ConnectionAcceptor_OnPlayerApproval", args); }
public static void ConnectionAcceptor_OnPlayerDisconnected(ConnectionAcceptor connection, uLink.NetworkPlayer player) { object[] args = new object[] { connection, player }; Method.Invoke("RustExtended.RustHook.ConnectionAcceptor_OnPlayerDisconnected", args); }
public PlayerApprovalEvent(ConnectionAcceptor ca, NetworkPlayerApproval approval, ClientConnection cc, bool AboutToDeny, ulong steamid, string ip, string name) { this._ca = ca; this._cc = cc; this._approval = approval; this._deny = AboutToDeny; this._steamid = steamid; this._ip = ip; this._name = name; }
public ListenerConnectionDemuxer(IConnectionListener listener, TransportType transportType, int maxAccepts, int initialMaxPendingConnections, TimeSpan channelInitializationTimeout, ConnectionHandleDuplicated connectionHandleDuplicated) { this.transportType = transportType; this.connectionReaders = new List <InitialServerConnectionReader>(); this.connectionHandleDuplicated = connectionHandleDuplicated; this.acceptor = new ConnectionAcceptor(listener, maxAccepts, initialMaxPendingConnections, OnConnectionAvailable); this.channelInitializationTimeout = channelInitializationTimeout; this.onConnectionClosed = new ConnectionClosedCallback(OnConnectionClosed); this.onViaDecoded = new ViaDecodedCallback(OnViaDecoded); }
public static void SteamDeny(ClientConnection cc, NetworkPlayerApproval approval, string strReason, NetError errornum) { SteamDenyEvent sde = new SteamDenyEvent(cc, approval, strReason, errornum); if (OnSteamDeny != null) { OnSteamDeny(sde); } if (sde.ForceAllow) { return; } string deny = "Auth failed: " + strReason + " - " + cc.UserName + " (" + cc.UserID.ToString() + ")"; ConsoleSystem.Print(deny, false); approval.Deny((uLink.NetworkConnectionError)errornum); ConnectionAcceptor.CloseConnection(cc); Rust.Steam.Server.OnUserLeave(cc.UserID); }
public void Start(string ip, UInt16 port, uint readBufferSize, uint timeout, X509Certificate2 certificate, HttpRequestProcessor httpRequestHandler, ResponseMaker internalServerError, LogManager logger) { if (ConnectionAcceptor == null) { ConnectionAcceptor = new TcpListener(IPAddress.Parse(ip), port); } if (Sessions == null) { Sessions = new ConcurrentDictionary <ulong, Session>(); } this.ReadBufferSize = readBufferSize; this.Timeout = timeout; this.HttpRequestHandler = httpRequestHandler; this.GetInternalServerError = internalServerError; this.Certificate = certificate; this.Logger = logger; ConnectionAcceptor.Start(); ConnectionAcceptor.BeginAcceptTcpClient(new AsyncCallback(OnAccept), this.ConnectionAcceptor); }
public static void OnUserDisconnected(uLink.NetworkPlayer player, ConnectionAcceptor CA) { try { if (CA != null) { if (player != null) { object localData = player.GetLocalData(); if (localData != null) { RustServerManagement RSM = RustServerManagement.Get(); if (localData is NetUser) { NetUser user = (NetUser)localData; PlayerClient playerClient = user.playerClient; List<PlayerClient> possibleClient = new List<PlayerClient>(); try { if (playerClient == null || playerClient.netUser == null || playerClient.netPlayer == null || playerClient.userName == null) possibleClient = Array.FindAll(AllPlayerClients.ToArray(), (PlayerClient pc) => pc.netUser == user || pc.userID == user.userID || pc.netPlayer == user.networkPlayer || pc.netPlayer == player).ToList(); if (possibleClient.Count() == 1) playerClient = possibleClient[0]; if (possibleClient.Count == 0 || playerClient == null || playerClient.netUser == null || playerClient.netPlayer == null || playerClient.userName == null) { possibleClient.Clear(); LockedList<PlayerClient> playerClients = PlayerClient.All; possibleClient = Array.FindAll(playerClients.ToArray(), (PlayerClient pc) => pc.netUser == user || pc.userID == user.userID || pc.netPlayer == user.networkPlayer || pc.netPlayer == player).ToList(); } if (possibleClient.Count() == 1) playerClient = possibleClient[0]; if (possibleClient.Count == 0 || playerClient == null || playerClient.netUser == null || playerClient.netPlayer == null || playerClient.userName == null) { possibleClient.Clear(); List<PlayerClient> playerClients = RSM._playerClientList; possibleClient = Array.FindAll(playerClients.ToArray(), (PlayerClient pc) => pc.netUser == user || pc.userID == user.userID || pc.netPlayer == user.networkPlayer || pc.netPlayer == player).ToList(); } if (possibleClient.Count() == 1) playerClient = possibleClient[0]; if (possibleClient.Count == 0 || playerClient == null || playerClient.netUser == null || playerClient.netPlayer == null || playerClient.userName == null) playerClient = null; if (playerClient == null) conLog.Error("Could not find a proper playerclient after many tries!"); } catch (Exception ex) { conLog.Error("Could not find a proper playerclient: " + ex.ToString()); } if (user != null && playerClient != null) { if (latestPM.ContainsKey(playerClient)) latestPM.Remove(playerClient); if (latestRequests.ContainsKey(playerClient)) latestRequests.Remove(playerClient); if (latestFactionRequests.ContainsKey(playerClient)) latestFactionRequests.Remove(playerClient); if (killList.Contains(playerClient)) killList.Remove(playerClient); if (isTeleporting.Contains(playerClient)) isTeleporting.Remove(playerClient); if (isAccepting.Contains(playerClient)) isAccepting.Remove(playerClient); if (wasHit.Contains(playerClient)) wasHit.Remove(playerClient); if (inSafeZone.ContainsKey(playerClient)) inSafeZone.Remove(playerClient); if (inWarZone.ContainsKey(playerClient)) inWarZone.Remove(playerClient); if (firstPoints.ContainsKey(playerClient)) firstPoints.Remove(playerClient); if (secondPoints.ContainsKey(playerClient)) secondPoints.Remove(playerClient); if (blockedRequestsPer.ContainsKey(playerClient.userID.ToString())) { if (blockedRequestsPer[playerClient.userID.ToString()].Count < 1) blockedRequestsPer.Remove(playerClient.userID.ToString()); } if (teleportRequests.ContainsKey(playerClient)) teleportRequests.Remove(playerClient); if (AllPlayerClients.Contains(playerClient)) AllPlayerClients.Remove(playerClient); string leaveMessage = ""; if (Vars.enableLeave && !Vars.kickQueue.Contains(playerClient.userID.ToString()) && playerClient.userName.Length > 0) { leaveMessage = Vars.leaveMessage.Replace("$USER$", Vars.filterFullNames(playerClient.userName, playerClient.userID.ToString())); Broadcast.broadcastJoinLeave(leaveMessage); Vars.conLog.Chat("<BROADCAST ALL> " + Vars.botName + ": " + leaveMessage); } user.connection.netUser = null; CA.m_Connections.Remove(user.connection); bool b = true; if (Vars.kickQueue.Contains(playerClient.userID.ToString()) || playerClient.userName.Length == 0) { if (Vars.kickQueue.Contains(playerClient.userID.ToString())) Vars.kickQueue.Remove(playerClient.userID.ToString()); b = false; } try { if (playerClient != null) { if (user == null) user = playerClient.netUser; if (user != null) { try { Controllable controllable = playerClient.controllable; if (controllable != null) { Character forCharacter = controllable.character; try { RSM.SaveAvatar(forCharacter); } catch (Exception exception) { conLog.Error("SA: " + exception); } if (forCharacter != null) { try { RSM.ShutdownAvatar(forCharacter); } catch (Exception exception) { conLog.Error("SDA: " + exception); } try { Character.DestroyCharacter(forCharacter); } catch (Exception exception) { conLog.Error("CDC: " + exception); } } } try { RSM._playerClientList.Remove(playerClient); } catch (Exception ex) { conLog.Error("COULD NOT REMOEVE PLAYERCLIENT FROM LIST: " + ex.ToString()); } } catch (Exception ex) { conLog.Error("ECFC: " + ex.ToString()); } } else conLog.Info("COULD NOT EARSE CHARACTERS FOR CLIENT!"); } if (player == null) player = playerClient.netPlayer; if (player != null) NetCull.DestroyPlayerObjects(player); else conLog.Info("COULD NOT DESTROY PLAYER OBJECTS!"); if (user == null) user = playerClient.netUser; if (user != null) CullGrid.ClearPlayerCulling(user); else conLog.Info("COULD NOT CLEAR PLAYER CULLING!"); if (player == null) player = playerClient.netPlayer; if (player != null) NetCull.RemoveRPCs(player); else conLog.Info("COULD NOT REMOVE RPCS!"); } catch (Exception exception) { conLog.Error("#1: " + exception.ToString()); conLog.Error("DO NOT IGNORE THE ERROR ABOVE. THESE THINGS SHOULD NOT BE FAILING. EVER."); } if (b) conLog.Info("Player " + user.displayName + " (" + user.userID + ") disconnected. Data unloaded."); Rust.Steam.Server.OnUserLeave(user.connection.UserID); try { user.Dispose(); } catch (Exception exception2) { conLog.Error("#2: " + exception2.ToString()); conLog.Error("DO NOT IGNORE THE ERROR ABOVE. THESE THINGS SHOULD NOT BE FAILING. EVER."); } } else { conLog.Error("So... A user disconnected but his/her NetUser/PlayerClient was null... Shit. Things will break due to this."); LockedList<PlayerClient> playerClients = PlayerClient.All; foreach (PlayerClient pc in playerClients) { if (!AllPlayerClients.Contains(pc)) { conLog.Error("Fixing the issue with the PlayerClient..."); try { if (latestPM.ContainsKey(playerClient)) latestPM.Remove(playerClient); if (latestRequests.ContainsKey(playerClient)) latestRequests.Remove(playerClient); if (latestFactionRequests.ContainsKey(playerClient)) latestFactionRequests.Remove(playerClient); if (killList.Contains(playerClient)) killList.Remove(playerClient); if (isTeleporting.Contains(playerClient)) isTeleporting.Remove(playerClient); if (isAccepting.Contains(playerClient)) isAccepting.Remove(playerClient); if (wasHit.Contains(playerClient)) wasHit.Remove(playerClient); if (inSafeZone.ContainsKey(playerClient)) inSafeZone.Remove(playerClient); if (inWarZone.ContainsKey(playerClient)) inWarZone.Remove(playerClient); if (firstPoints.ContainsKey(playerClient)) firstPoints.Remove(playerClient); if (secondPoints.ContainsKey(playerClient)) secondPoints.Remove(playerClient); if (blockedRequestsPer.ContainsKey(playerClient.userID.ToString())) { if (blockedRequestsPer[playerClient.userID.ToString()].Count < 1) blockedRequestsPer.Remove(playerClient.userID.ToString()); } if (teleportRequests.ContainsKey(playerClient)) teleportRequests.Remove(playerClient); if (AllPlayerClients.Contains(playerClient)) AllPlayerClients.Remove(playerClient); string leaveMessage = ""; if (Vars.enableLeave && !Vars.kickQueue.Contains(playerClient.userID.ToString()) && playerClient.userName.Length > 0) { leaveMessage = Vars.leaveMessage.Replace("$USER$", Vars.filterFullNames(playerClient.userName, playerClient.userID.ToString())); Broadcast.broadcastJoinLeave(leaveMessage); Vars.conLog.Chat("<BROADCAST ALL> " + Vars.botName + ": " + leaveMessage); } user.connection.netUser = null; CA.m_Connections.Remove(user.connection); bool b = true; if (Vars.kickQueue.Contains(playerClient.userID.ToString()) || playerClient.userName.Length == 0) { if (Vars.kickQueue.Contains(playerClient.userID.ToString())) Vars.kickQueue.Remove(playerClient.userID.ToString()); b = false; } try { if (playerClient != null) { RSM.EraseCharactersForClient(playerClient, true, user); } NetCull.DestroyPlayerObjects(player); CullGrid.ClearPlayerCulling(user); NetCull.RemoveRPCs(player); } catch (Exception exception) { conLog.Error("#3: " + exception.ToString()); conLog.Error("DO NOT IGNORE THE ERROR ABOVE. THESE THINGS SHOULD NOT BE FAILING. EVER."); } if (b) conLog.Info("Player " + user.displayName + " (" + user.userID + ") disconnected. Data unloaded."); Rust.Steam.Server.OnUserLeave(user.connection.UserID); try { user.Dispose(); } catch (Exception exception2) { conLog.Error("#4: " + exception2.ToString()); conLog.Error("DO NOT IGNORE THE ERROR ABOVE. THESE THINGS SHOULD NOT BE FAILING. EVER."); } } catch (Exception ex) { conLog.Error("Something went TERRIBLY TERRIBLY wrong. Contact MistaD ASAP. Send him this: " + ex.ToString()); } } } } } else if (localData is ClientConnection) { ClientConnection item = (ClientConnection)localData; CA.m_Connections.Remove(item); ConsoleSystem.Print("User Disconnected: (unconnected " + player.ipAddress + ")", false); } player.SetLocalData(null); Rust.Steam.Server.OnPlayerCountChanged(); } else conLog.Error("User attempted to disconnect but the localData was corrupted."); } else conLog.Error("User attempted to disconnect but the NetworkPlayer was corrupted."); } } catch (Exception ex) { Vars.conLog.Error("OUD: " + ex.ToString()); } }
private static void Accept(ConnectionAcceptor ca, NetworkPlayerApproval approval, ClientConnection clientConnection) { ca.m_Connections.Add(clientConnection); ca.StartCoroutine(clientConnection.AuthorisationRoutine(approval)); approval.Wait(); }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return(true); } var id = connection.UserID.ToString(); var ip = approval.ipAddress; // Call out and see if we should reject var loginSpecific = Interface.Call("CanClientLogin", connection); var loginCovalence = Interface.Call("CanUserLogin", connection.UserName, id, ip); var canLogin = loginSpecific ?? loginCovalence; // Check if player can login if (canLogin is string || (canLogin is bool && !(bool)canLogin)) { // Reject the user with the message Notice.Popup(connection.netUser.networkPlayer, "", canLogin is string?canLogin.ToString() : "Connection was rejected", 10f); // TODO: Localization approval.Deny(uLink.NetworkConnectionError.NoError); return(true); } // Call the approval hooks var approvedSpecific = Interface.Call("OnUserApprove", connection, approval, acceptor); var approvedCovalence = Interface.Call("OnUserApproved", connection.UserName, id, ip); return(approvedSpecific ?? approvedCovalence); }
private void OnUserApprove(ClientConnection connection, uLink.NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { HookCalled("OnUserApprove"); }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return false; } // Call out and see if we should reject var canlogin = Interface.CallHook("CanClientLogin", connection); if (canlogin is uLink.NetworkConnectionError) { approval.Deny((uLink.NetworkConnectionError)canlogin); return true; } return Interface.CallHook("OnUserApprove", connection, approval, acceptor); }
private object OnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { var result = Interface.CallHook("CanClientLogin", connection, approval); if (result is uLink.NetworkConnectionError) { approval.Deny((uLink.NetworkConnectionError)result); return false; } return null; }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return(false); } // Call out and see if we should reject var canlogin = Interface.CallHook("CanClientLogin", connection); if (canlogin is uLink.NetworkConnectionError) { approval.Deny((uLink.NetworkConnectionError)canlogin); return(true); } return(Interface.CallHook("OnUserApprove", connection, approval, acceptor)); }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return false; } var result = Interface.CallHook("CanClientLogin", connection, approval); if (result is uLink.NetworkConnectionError) { approval.Deny((uLink.NetworkConnectionError)result); return false; } return Interface.CallHook("OnUserApprove", connection, approval, acceptor); }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return(true); } // Call out and see if we should reject var canlogin = Interface.CallHook("CanClientLogin", connection) ?? Interface.CallHook("CanUserLogin", connection.UserName, connection.UserID.ToString()); if (canlogin != null) { Notice.Popup(connection.netUser.networkPlayer, "", canlogin.ToString(), 10f); approval.Deny(uLink.NetworkConnectionError.NoError); return(true); } return(Interface.CallHook("OnUserApprove", connection, approval, acceptor) ?? Interface.CallHook("OnUserApproved", connection.UserName, connection.UserID.ToString())); }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return(true); } // "Already connected" fix var netUser = NetUser.FindByUserID(connection.UserID); if (netUser != null) { Interface.Oxide.LogInfo($"Kicking existing {netUser.displayName} ({netUser.userID}) player (already connected fix)"); netUser.Kick(NetError.AlreadyConnectedToAnotherServer, false); } var id = connection.UserID.ToString(); var ip = approval.ipAddress; Covalence.PlayerManager.PlayerJoin(connection.UserID, connection.UserName); // TODO: Handle this automatically // Call out and see if we should reject var loginSpecific = Interface.Call("CanClientLogin", connection); var loginCovalence = Interface.Call("CanUserLogin", connection.UserName, id, ip); var canLogin = loginSpecific ?? loginCovalence; // TODO: Fix 'RustLegacyCore' hook conflict when both return // Check if player can login if (canLogin is string || (canLogin is bool && !(bool)canLogin)) { // Reject the player with the message Notice.Popup(connection.netUser.networkPlayer, "", canLogin is string?canLogin.ToString() : "Connection was rejected", 10f); // TODO: Localization approval.Deny(uLink.NetworkConnectionError.NoError); return(true); } // Call the approval hooks var approvedSpecific = Interface.Call("OnUserApprove", connection, approval, acceptor); var approvedCovalence = Interface.Call("OnUserApproved", connection.UserName, id, ip); return(approvedSpecific ?? approvedCovalence); // TODO: Fix 'RustLegacyCore' hook conflict when both return }
public static void PlayerApproval(ConnectionAcceptor ca, NetworkPlayerApproval approval) { if (ca.m_Connections.Count >= server.maxplayers) { approval.Deny(uLink.NetworkConnectionError.TooManyConnectedPlayers); } else { ClientConnection clientConnection = new ClientConnection(); if (!clientConnection.ReadConnectionData(approval.loginData)) { approval.Deny(uLink.NetworkConnectionError.IncorrectParameters); return; } Fougerite.Server srv = Fougerite.Server.GetServer(); ulong uid = clientConnection.UserID; string ip = approval.ipAddress; string name = clientConnection.UserName; if (clientConnection.Protocol != 1069) { Debug.Log((object)("Denying entry to client with invalid protocol version (" + ip + ")")); approval.Deny(uLink.NetworkConnectionError.IncompatibleVersions); } else if (BanList.Contains(uid)) { Debug.Log((object)("Rejecting client (" + uid.ToString() + "in banlist)")); approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); } else if (srv.IsBannedID(uid.ToString()) || srv.IsBannedIP(ip)) { if (!srv.IsBannedIP(ip)) { srv.BanPlayerIP(ip, name + "-Console"); Logger.LogDebug("[FougeriteBan] Detected banned ID, but IP is not banned: " + name + " - " + ip + " - " + uid); } if (!srv.IsBannedID(uid.ToString())) { srv.BanPlayerID(uid.ToString(), name + "-Console"); Logger.LogDebug("[FougeriteBan] Detected banned IP, but ID is not banned: " + name + " - " + ip + " - " + uid); } Debug.Log("[FougeriteBan] Disconnected: " + name + " - " + ip + " - " + uid, null); Logger.LogDebug("[FougeriteBan] Disconnected: " + name + " - " + ip + " - " + uid); approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); } else if (ca.IsConnected(clientConnection.UserID)) { PlayerApprovalEvent ape = new PlayerApprovalEvent(ca, approval, clientConnection, true); if (OnPlayerApproval != null) { OnPlayerApproval(ape); } if (ape.ForceAccept && !ape.ServerHasPlayer) { Accept(ca, approval, clientConnection); return; } Debug.Log((object)("Denying entry to " + uid.ToString() + " because they're already connected")); approval.Deny(uLink.NetworkConnectionError.AlreadyConnectedToAnotherServer); } else { PlayerApprovalEvent ape = new PlayerApprovalEvent(ca, approval, clientConnection, false); if (OnPlayerApproval != null) { OnPlayerApproval(ape); } Accept(ca, approval, clientConnection); } } }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { var id = connection.UserID.ToString(); var ip = approval.ipAddress; // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return true; } // Migrate user from 'player' group to 'default' if (permission.UserHasGroup(id, "player")) { permission.AddUserGroup(id, "default"); permission.RemoveUserGroup(id, "player"); Interface.Oxide.LogWarning($"Migrated '{id}' to the new 'default' group"); } // Call out and see if we should reject var canLogin = (string)Interface.Call("CanClientLogin", connection) ?? Interface.Call("CanUserLogin", connection.UserName, id, ip); if (canLogin is string) { // Reject the user with the message Notice.Popup(connection.netUser.networkPlayer, "", canLogin.ToString(), 10f); approval.Deny(uLink.NetworkConnectionError.NoError); return true; } return Interface.Call("OnUserApprove", connection, approval, acceptor) ?? Interface.Call("OnUserApproved", connection.UserName, id, ip); }
public void StopListening() { ConnectionAcceptor?.Stop(); ConnectionAcceptor = null; }
private object IOnUserApprove(ClientConnection connection, NetworkPlayerApproval approval, ConnectionAcceptor acceptor) { var id = connection.UserID.ToString(); // Reject invalid connections if (connection.UserID == 0 || string.IsNullOrEmpty(connection.UserName)) { approval.Deny(uLink.NetworkConnectionError.ConnectionBanned); return(true); } // Migrate user from 'player' group to 'default' if (permission.UserHasGroup(id, "player")) { permission.AddUserGroup(id, "default"); permission.RemoveUserGroup(id, "player"); Interface.Oxide.LogWarning($"Migrated '{id}' to the new 'default' group"); } // Call out and see if we should reject var canlogin = (string)Interface.CallHook("CanClientLogin", connection) ?? Interface.CallHook("CanUserLogin", connection.UserName, id); if (canlogin is string) { Notice.Popup(connection.netUser.networkPlayer, "", canlogin.ToString(), 10f); approval.Deny(uLink.NetworkConnectionError.NoError); return(true); } return(Interface.CallHook("OnUserApprove", connection, approval, acceptor) ?? Interface.CallHook("OnUserApproved", connection.UserName, id)); }