/// <summary> /// Rcon thread connection /// </summary> public void ConnectionThread() { while (true) { TcpClient client = null; while (true) { try { client = new TcpClient(); client.Connect("127.0.0.1", GetPort()); break; } catch (Exception ex) { //SSNL.Log(this, "Failed to connect to rcon, retrying... (" + ex.Message + ")"); } } srv_reader = new StreamReader(client.GetStream(), Encoding.UTF8); srv_writer = new StreamWriter(client.GetStream(), Encoding.UTF8) { NewLine = "\r\n", AutoFlush = true }; try { RconSend(GetRconPassword()); SSNL.Log(this, "Rcon connected"); RconSend("prj_strDisabledVoteTypes=\"" + GetDisallowedVotes() + "\""); RconSend("prj_bExitOnSessionEnd=true"); } catch { } // we won't get information about current players - we don't care much about that... SSNL.DB.Query("DELETE FROM `activeplayers` WHERE `Server`=" + srv_rowServer["ID"]); SSNL.DB.Query("UPDATE `Servers` SET `_Players`=0 WHERE `ID`=" + srv_rowServer["ID"]); srv_ctPlayers = 0; while (true) { string strLine = ""; try { strLine = srv_reader.ReadLine(); } catch { SSNL.Log(this, "Lost connection"); break; } if (strLine == null) { SSNL.Log(this, "Line reading error"); break; } if (strLine.StartsWith("Server accepted connection from IP: ")) { string[] parse = strLine.Split(new string[] { ": ", ", ", "." }, StringSplitOptions.None); string strSteamID = parse[1]; int iPlayerIndex = int.Parse(parse[3]); if (IsPrivate()) { Whitelist whitelist = GetWhitelist(); if (!whitelist.IsPlayerWhitelisted(strSteamID)) { SSNL.Log(this, "Player with ID " + strSteamID + " is not allowed to play in this server - kicking!"); RconSend("Wait(Delay(4));samKickClient(" + iPlayerIndex + ");"); break; } } SSNL.Log(this, "Player with ID " + strSteamID + " is connecting"); } else if (strLine.StartsWith("<")) { XMLTag tag = SimpleXMLReader.Parse(strLine); string strPlayer = ""; if (tag.Attributes.ContainsKey("player")) { strPlayer = tag["player"]; } switch (tag.Name) { case "playerjoined": if (IsServerStrict()) { RconSend("chatSay(\"~ " + SSNL.LuaSafe(strPlayer) + ", this is a STRICT server. Please see: serioussam.nl/strict\")"); } SSNL.Log(this, strPlayer + " joined"); break; case "playerleft": SSNL.Log(this, strPlayer + " left"); break; case "chat": if (strPlayer == "") { // ignore messages from server break; } if (tag.Content.StartsWith("/")) { string[] strParse = tag.Content.Split(' '); switch (strParse[0]) { case "/stats": RconSend("chatSay(\"~ We don't track stats yet. :)\")"); break; } } SSNL.Log(this, HtmlDecode(strPlayer) + ": " + tag.Content); break; case "playerkilled": int iLastWarning = 2; string strWeapon = tag["damageinflictorweapon"]; string strKiller = tag["killerplayer"]; string strKillerId = tag["killerplayerid"]; if (strKiller == "") { SSNL.Log(this, HtmlDecode(strPlayer) + " died"); } else if (strKiller == strPlayer) { SSNL.Log(this, HtmlDecode(strPlayer) + " killed himself"); } else { SSNL.Log(this, HtmlDecode(strKiller) + " killed " + HtmlDecode(strPlayer)); } break; } } } // if the server was supposed to close if (srv_bClosing) { // don't attempt to reconnect break; } } }
/// <summary> /// Rcon thread connection /// </summary> public void ConnectionThread() { while (true) { TcpClient client = null; while (true) { try { client = new TcpClient(); client.Connect("127.0.0.1", GetPort()); break; } catch (Exception ex) { //SSNL.Log(this, "Failed to connect to rcon, retrying... (" + ex.Message + ")"); } } srv_reader = new StreamReader(client.GetStream(), Encoding.UTF8); srv_writer = new StreamWriter(client.GetStream(), Encoding.UTF8) { NewLine = "\r\n", AutoFlush = true }; try { RconSend(GetRconPassword()); SSNL.Log(this, "Rcon connected"); RconSend("prj_bExitOnSessionEnd=true"); RconSend("gam_bInfiniteAmmo=" + srv_rowServer["InfiniteAmmo"]); } catch { } // we won't get information about current players - we don't care much about that... SSNL.DB.Query("DELETE FROM `activeplayers` WHERE `Server`=" + srv_rowServer["ID"]); SSNL.DB.Query("UPDATE `Servers` SET `_Players`=0 WHERE `ID`=" + srv_rowServer["ID"]); srv_ctPlayers = 0; while (true) { string strLine = ""; try { strLine = srv_reader.ReadLine(); } catch { SSNL.Log(this, "Lost connection"); break; } if (strLine == null) { SSNL.Log(this, "Line reading error"); break; } if (strLine.StartsWith("Server accepted connection from IP: ")) { string[] parse = strLine.Split(new string[] { ": ", ", ", "." }, StringSplitOptions.None); string strSteamID = parse[1]; int iPlayerIndex = int.Parse(parse[3]); srv_aPlayerIndices[iPlayerIndex] = strSteamID; if (SSNL.DB.Query("SELECT * FROM `activeplayers` WHERE `Server`=" + srv_rowServer["ID"] + " AND `SteamID`='" + strSteamID + "'").Length == 0) { SSNL.DB.Query("INSERT INTO `activeplayers` (`Server`,`Spectating`,`SteamID`,`Name`,`Frags`,`Deaths`) VALUES(" + srv_rowServer["ID"] + ",1,'" + strSteamID + "','',0,0)"); } UpdatePlayerCount(); if (IsPrivate()) { Whitelist whitelist = GetWhitelist(); if (!whitelist.IsPlayerWhitelisted(strSteamID)) { SSNL.Log(this, "Player with ID " + strSteamID + " is not allowed to play in this server - kicking!"); RconSend("Wait(Delay(4));gamKickByIP(\"" + strSteamID + "\");"); break; } } SSNL.Log(this, "Player with ID " + strSteamID + " is connecting"); } else if ( strLine.StartsWith("Server received a disconnect message from ") || strLine.StartsWith("Server sent a disconnect message to ") || strLine.StartsWith("Server terminating client ")) { int iPlayerIndex = int.Parse(strLine.Split(new string[] { "from ", "to ", "client ", "." }, StringSplitOptions.None)[1]); SSNL.DB.Query("DELETE FROM `activeplayers` WHERE `SteamID`='" + srv_aPlayerIndices[iPlayerIndex] + "'"); srv_aPlayerIndices[iPlayerIndex] = ""; UpdatePlayerCount(); } else if (strLine.StartsWith("<")) { XMLTag tag = SimpleXMLReader.Parse(strLine); string strPlayer = ""; string strPlayerId = ""; int iAdmin = 0; if (tag.Attributes.ContainsKey("player")) { strPlayer = tag["player"]; } if (tag.Attributes.ContainsKey("playerid")) { strPlayerId = tag["playerid"]; } switch (tag.Name) { case "playerjoined": if (!srv_dicPlayers.ContainsKey(strPlayerId)) { srv_dicPlayers[strPlayerId] = new Player(); } else { srv_dicPlayers[strPlayerId].ResetStats(); } srv_dicPlayers[strPlayerId].ply_strName = strPlayer; SSNL.DB.Query("UPDATE `activeplayers` SET `Spectating`=0,`Name`='" + SSNL.DB.Safe(strPlayer) + "' WHERE `SteamID`='" + strPlayerId + "'"); if (IsServerStrict()) { RconSend("chatSay(\"~ " + SSNL.LuaSafe(strPlayer) + ", this is a STRICT server. Please see: serioussam.nl/strict\")"); } SSNL.Log(this, strPlayer + " joined"); break; case "playerleft": if (srv_dicPlayers.ContainsKey(strPlayerId)) { srv_dicPlayers.Remove(strPlayerId); } SSNL.Log(this, strPlayer + " left"); break; case "roundstart": srv_strCurrentGameMode = tag["gamemode"]; srv_iCurrentFragLimit = int.Parse(tag["fraglimit"]); srv_iCurrentTimeLimit = int.Parse(tag["timelimit"]); srv_iCurrentGoalsLimit = int.Parse(tag["goalslimit"]); srv_iCurrentMinPlayers = int.Parse(tag["minplayers"]); srv_iCurrentMaxPlayers = int.Parse(tag["maxplayers"]); srv_bCurrentJoinInProgress = tag["joininprogress"] == "1"; SSNL.DB.Query("UPDATE `activeplayers` SET `Spectating`=1,`Frags`=0,`Deaths`=0 WHERE `Server`=" + srv_rowServer["ID"]); SSNL.Log(this, "Round starting"); break; case "chat": if (strPlayer == "" || strPlayerId == "[admin]") { // ignore messages from server break; } if (tag.Content.StartsWith("/")) { iAdmin = SSNL.IsPlayerAdmin(strPlayerId); string[] strParse = tag.Content.Split(' '); switch (strParse[0]) { case "/stats": RconSend("chatSay(\"~ We don't track stats yet. :)\")"); break; } } SSNL.DB.Query("UPDATE `activeplayers` SET `Name`='" + SSNL.DB.Safe(strPlayer) + "' WHERE `SteamID`='" + strPlayerId + "'"); // if player is using chatSay("\n"), kick! *giggles* if (tag.Content.Contains("\n")) { RconSend("gamKickByIP(\"" + strPlayerId + "\")"); } SSNL.Log(this, HtmlDecode(strPlayer) + ": " + tag.Content); break; case "playerkilled": int iLastWarning = 2; string strWeapon = tag["damageinflictorweapon"]; string strKiller = tag["killerplayer"]; string strKillerId = tag["killerplayerid"]; if (strKiller == "") { SSNL.Log(this, HtmlDecode(strPlayer) + " died"); } else if (strKiller == strPlayer) { SSNL.Log(this, HtmlDecode(strPlayer) + " killed himself"); } else { SSNL.Log(this, HtmlDecode(strKiller) + " killed " + HtmlDecode(strPlayer)); } if (srv_dicPlayers.ContainsKey(strPlayerId)) { srv_dicPlayers[strPlayerId].ply_iDeaths++; SSNL.DB.Query("UPDATE `activeplayers` SET `Deaths`=`Deaths`+1 WHERE `SteamID`='" + strPlayerId + "'"); } if (strKillerId != "") { if (srv_dicPlayers.ContainsKey(strKillerId)) { srv_dicPlayers[strKillerId].ply_iKills++; SSNL.DB.Query("UPDATE `activeplayers` SET `Frags`=`Frags`+1 WHERE `SteamID`='" + strKillerId + "'"); } } // if strict server if (IsServerStrict()) { // disallowing of certain weapons if (srv_strCurrentGameMode != "InstantKill") { string[] strDisallowedWeapons = { "Cannon", "Sniper", "Chainsaw" }; // if disallowed weapon used if (strDisallowedWeapons.Contains(strWeapon)) { // if this player already received the max amount of warnings about disallowed weapons if (srv_dicPlayers.ContainsKey(strKillerId)) { if (srv_dicPlayers[strKillerId].ply_iWarnings == iLastWarning) { SSNL.Log("Player " + strKiller + " (" + strKillerId + ") got kicked for disallowed weapon usage: " + strWeapon); RconSend("chatSay(\"~ Kicking " + SSNL.LuaSafe(strKiller) + " for disallowed weapon usage.\")"); RconSend("gamKickByIP(\"" + strKillerId + "\")"); } else { SSNL.Log("Player " + strKiller + " (" + strKillerId + ") got a warning for disallowed weapon usage: " + strWeapon); srv_dicPlayers[strKillerId].ply_iWarnings++; RconSend("chatSay(\"~ " + (srv_dicPlayers[strKillerId].ply_iWarnings == iLastWarning ? "FINAL WARNING" : "WARNING") + ": " + SSNL.LuaSafe(strKiller) + ", " + strWeapon + " is NOT ALLOWED!!\")"); } } } } } break; } } } // if the server was supposed to close if (srv_bClosing) { // don't attempt to reconnect break; } } }