-stability fixes

-welcome has post-fixed connection indicator
This commit is contained in:
RaidMax 2015-03-14 11:42:36 -05:00
parent 73dfb9a612
commit b0e32e9a91
11 changed files with 193 additions and 74 deletions

View File

@ -467,6 +467,7 @@ namespace IW4MAdmin
public override void Execute(Event E) public override void Execute(Event E)
{ {
E.Data = Utilities.removeWords(E.Data, 1);
E.Target.Tell("^1" + E.Origin.getName() + " ^3[PM]^7 - " + E.Data); E.Target.Tell("^1" + E.Origin.getName() + " ^3[PM]^7 - " + E.Data);
E.Origin.Tell(String.Format("To ^3{0} ^7-> {1}", E.Target.getName(), E.Data)); E.Origin.Tell(String.Format("To ^3{0} ^7-> {1}", E.Target.getName(), E.Data));
} }

View File

@ -350,7 +350,7 @@ namespace IW4MAdmin
//Returns top 8 players (we filter through them later) //Returns top 8 players (we filter through them later)
public List<Stats> topStats() public List<Stats> topStats()
{ {
String Query = String.Format("SELECT * FROM STATS WHERE SKILL > '{0}' ORDER BY SKILL DESC LIMIT 8", 20); String Query = String.Format("SELECT * FROM STATS WHERE SKILL > '{0}' ORDER BY SKILL DESC LIMIT 8", 10);
DataTable Result = GetDataTable(Query); DataTable Result = GetDataTable(Query);
List<Stats> Top = new List<Stats>(); List<Stats> Top = new List<Stats>();
@ -360,7 +360,7 @@ namespace IW4MAdmin
foreach (DataRow D in Result.Rows) foreach (DataRow D in Result.Rows)
{ {
Stats S = new Stats(Convert.ToInt32(D["Number"]), Convert.ToInt32(D["DEATHS"]), Convert.ToDouble(D["KDR"]), Convert.ToDouble(D["SKILL"])); Stats S = new Stats(Convert.ToInt32(D["Number"]), Convert.ToInt32(D["DEATHS"]), Convert.ToDouble(D["KDR"]), Convert.ToDouble(D["SKILL"]));
if (S.Skill > 20) if (S.Skill > 10)
Top.Add(S); Top.Add(S);
} }
} }

View File

@ -58,7 +58,9 @@ namespace IW4MAdmin
public static Event requestEvent(String[] line, Server SV) public static Event requestEvent(String[] line, Server SV)
{ {
#if DEBUG == false
try try
#endif
{ {
String eventType = line[0].Substring(line[0].Length - 1); String eventType = line[0].Substring(line[0].Length - 1);
eventType = eventType.Trim(); eventType = eventType.Trim();
@ -76,7 +78,7 @@ namespace IW4MAdmin
{ {
if (line.Length < 4) if (line.Length < 4)
{ {
Console.WriteLine("SAY FUCKED UP"); Console.WriteLine("SAY FUCKED UP BIG-TIME");
return null; return null;
} }
Regex rgx = new Regex("[^a-zA-Z0-9 -! -_]"); Regex rgx = new Regex("[^a-zA-Z0-9 -! -_]");
@ -93,11 +95,13 @@ namespace IW4MAdmin
return null; return null;
} }
#if DEBUG == false
catch (Exception E) catch (Exception E)
{ {
SV.Log.Write("Error requesting event " + E.Message, Log.Level.Debug); SV.Log.Write("Error requesting event " + E.Message, Log.Level.Debug);
return null; return null;
} }
#endif
} }

View File

@ -29,6 +29,7 @@ namespace IW4MAdmin
{ {
Name = file; Name = file;
writeHandle = new StreamWriter(new FileStream(Name, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); writeHandle = new StreamWriter(new FileStream(Name, FileMode.Create, FileAccess.Write, FileShare.ReadWrite));
// writeHandle.AutoFlush = true;
sze = 0; sze = 0;
} }

View File

@ -28,8 +28,8 @@
<PublisherName>RaidMax LLC</PublisherName> <PublisherName>RaidMax LLC</PublisherName>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish> <CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>publish.htm</WebPage> <WebPage>publish.htm</WebPage>
<ApplicationRevision>6</ApplicationRevision> <ApplicationRevision>7</ApplicationRevision>
<ApplicationVersion>0.4.0.%2a</ApplicationVersion> <ApplicationVersion>0.6.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust> <UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted> <PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled> <BootstrapperEnabled>true</BootstrapperEnabled>

View File

@ -10,7 +10,7 @@ namespace IW4MAdmin
static String IP; static String IP;
static int Port; static int Port;
static String RCON; static String RCON;
static public double Version = 0.5; static public double Version = 0.6;
static public double latestVersion; static public double latestVersion;
static void Main(string[] args) static void Main(string[] args)

View File

@ -100,7 +100,10 @@ namespace IW4MAdmin
Level = (Player.Permission)l; Level = (Player.Permission)l;
LastOffense = null; LastOffense = null;
Connections = 0; Connections = 0;
IP = "";
Warnings = 0; Warnings = 0;
Alias = new Aliases(0, "", "");
stats = new Stats(0, 0, 0, 1);
} }
public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2) public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2)

View File

@ -101,7 +101,7 @@ namespace IW4MAdmin
public void ManageRCONQueue() public void ManageRCONQueue()
{ {
while (true) while (Instance.isRunning)
{ {
if (toSend.Count > 0) if (toSend.Count > 0)
{ {

View File

@ -100,10 +100,71 @@ namespace IW4MAdmin
return Bans; return Bans;
} }
public void threadedConnect(Player P, Player NewPlayer)
{
bool updated = false;
while (!updated)
{
try
{
P.updateIP(IPS[P.getID()].Trim());
updated = true;
Log.Write("Sucessfully updated " + NewPlayer.getName() + "'s IP to " + P.getIP(), Log.Level.Debug);
}
catch
{
//Log.Write("Looks like the connecting player doesn't have an IP location assigned yet. Let's wait for next poll", Log.Level.Debug);
Utilities.Wait(1);
}
}
if (NewPlayer.Alias == null)
{
aliasDB.addPlayer(new Aliases(NewPlayer.getDBID(), NewPlayer.getName(), P.getIP()));
}
if (P.getName() != NewPlayer.getName())
{
NewPlayer.updateName(P.getName());
NewPlayer.Alias.addName(P.getName());
aliasDB.updatePlayer(NewPlayer.Alias);
}
if (P.getIP() != NewPlayer.getIP())
{
NewPlayer.updateIP(P.getIP());
NewPlayer.Alias.addIP(P.getIP());
aliasDB.updatePlayer(NewPlayer.Alias);
}
clientDB.updatePlayer(NewPlayer);
Ban B = isBanned(NewPlayer);
if (B != null || NewPlayer.getLevel() == Player.Permission.Banned)
{
Log.Write("Banned client " + P.getName() + " trying to connect...", Log.Level.Debug);
string Reason = String.Empty;
if (B != null)
Reason = B.getReason();
else
Reason = P.LastOffense;
String Message = "^1Player Kicked: ^7Previously Banned for ^5" + Reason;
P.Kick(Message);
}
players[NewPlayer.getClientNum()] = null;
players[NewPlayer.getClientNum()] = NewPlayer;
}
//Add player object p to `players` list //Add player object p to `players` list
public bool addPlayer(Player P) public bool addPlayer(Player P)
{ {
#if DEBUG == false
try try
#endif
{ {
if (clientDB.getPlayer(P.getID(), P.getClientNum()) == null) if (clientDB.getPlayer(P.getID(), P.getClientNum()) == null)
{ {
@ -117,68 +178,38 @@ namespace IW4MAdmin
//messy way to prevent loss of last event //messy way to prevent loss of last event
Player NewPlayer = clientDB.getPlayer(P.getID(), P.getClientNum()); Player NewPlayer = clientDB.getPlayer(P.getID(), P.getClientNum());
NewPlayer.stats = statDB.getStats(NewPlayer.getDBID()); NewPlayer.stats = statDB.getStats(NewPlayer.getDBID());
if (NewPlayer.stats == null) NewPlayer.Alias = aliasDB.getPlayer(NewPlayer.getDBID());
if (NewPlayer.stats == null) //For safety
{ {
statDB.addPlayer(NewPlayer); statDB.addPlayer(NewPlayer);
NewPlayer.stats = statDB.getStats(NewPlayer.getDBID()); NewPlayer.stats = statDB.getStats(NewPlayer.getDBID());
} }
NewPlayer.Alias = aliasDB.getPlayer(NewPlayer.getDBID());
if (P.lastEvent == null)
NewPlayer.lastEvent = new Event(Event.GType.Say, null, NewPlayer, null, this); // this is messy but its throwing an error when they've started it too late
else
NewPlayer.lastEvent = P.lastEvent; NewPlayer.lastEvent = P.lastEvent;
if (players[NewPlayer.getClientNum()] == null) if (players[NewPlayer.getClientNum()] == null)
{ {
try Thread connectThread = new Thread(() => threadedConnect(P, NewPlayer));
{ connectThread.Start(); // We don't want events to get behind
P.updateIP(IPS[P.getID()]);
}
catch
{
Log.Write("Looks like the connecting player doesn't have an IP location assigned yet.", Log.Level.Debug);
P.updateIP(getPlayerIP(P.getID()));
}
if (P.getName() != NewPlayer.getName())
{
NewPlayer.updateName(P.getName());
NewPlayer.Alias.addName(P.getName());
}
if (P.getIP() != NewPlayer.getIP())
{
NewPlayer.updateIP(P.getIP());
NewPlayer.Alias.addIP(P.getIP());
}
NewPlayer.Tell("Welcome ^5" + NewPlayer.getName() + " ^7this is your ^5" + Utilities.timesConnected(NewPlayer.getConnections()) + " ^7time connecting!");
Log.Write("Client " + NewPlayer.getName() + " connecting...", Log.Level.Debug);
clientnum++; clientnum++;
} }
NewPlayer.lastEvent = P.lastEvent;
players[NewPlayer.getClientNum()] = null;
players[NewPlayer.getClientNum()] = NewPlayer;
Ban B = isBanned(NewPlayer);
if (NewPlayer.getLevel() == Player.Permission.Banned || B != null)
{
Log.Write("Banned client " + P.getName() + " trying to connect...", Log.Level.Debug);
String Message = "^1Player Kicked: ^7Previously Banned for ^5" + B.getReason();
P.Kick(Message);
}
else
Log.Write("Client " + NewPlayer.getName() + " connecting...", Log.Level.Debug);
clientDB.updatePlayer(NewPlayer);
aliasDB.updatePlayer(NewPlayer.Alias);
return true; return true;
} }
#if DEBUG == false
catch (Exception E) catch (Exception E)
{ {
Log.Write("Unable to add player " + P.getName() + " - " + E.Message, Log.Level.Debug); Log.Write("Unable to add player " + P.getName() + " - " + E.Message, Log.Level.Debug);
return false; return false;
} }
#endif
} }
//Remove player by CLIENT NUMBER //Remove player by CLIENT NUMBER
@ -214,7 +245,8 @@ namespace IW4MAdmin
} }
Log.Write("Could not find player but player is in server. Lets try to manually add (looks like you didn't start me on an empty server)", Log.Level.All); Log.Write("Could not find player but player is in server. Lets try to manually add (looks like you didn't start me on an empty server)", Log.Level.All);
addPlayer(new Player(Name, line[1].ToString(), Convert.ToInt16(line[2]), 0)); players[Convert.ToInt16(line[2])] = null;
addPlayer(new Player(Name, line[1].ToString().Trim(), Convert.ToInt16(line[2]), 0));
return players[Convert.ToInt16(line[2])]; return players[Convert.ToInt16(line[2])];
} }
} }
@ -326,7 +358,7 @@ namespace IW4MAdmin
private void manageEventQueue() private void manageEventQueue()
{ {
while (true) while (isRunning)
{ {
if (events.Count > 0) if (events.Count > 0)
{ {
@ -340,6 +372,7 @@ namespace IW4MAdmin
//Starts the monitoring process //Starts the monitoring process
public void Monitor() public void Monitor()
{ {
isRunning = true;
//Handles new rcon requests in a fashionable manner //Handles new rcon requests in a fashionable manner
Thread RCONQueue = new Thread(new ThreadStart(RCON.ManageRCONQueue)); Thread RCONQueue = new Thread(new ThreadStart(RCON.ManageRCONQueue));
@ -348,32 +381,41 @@ namespace IW4MAdmin
if (!intializeBasics()) if (!intializeBasics())
{ {
Log.Write("Stopping " + Port + " due to uncorrectable errors (check log)" + logPath, Log.Level.Production); Log.Write("Stopping " + Port + " due to uncorrectable errors (check log)" + logPath, Log.Level.Production);
isRunning = false;
Utilities.Wait(10); Utilities.Wait(10);
return; return;
} }
Thread statusUpdate = new Thread(new ThreadStart(pollServer));
statusUpdate.Start();
//Handles new events in a fashionable manner //Handles new events in a fashionable manner
Thread eventQueue = new Thread(new ThreadStart(manageEventQueue)); Thread eventQueue = new Thread(new ThreadStart(manageEventQueue));
eventQueue.Start(); eventQueue.Start();
int timesFailed = 0; int timesFailed = 0;
long l_size = -1; long l_size = -1;
bool checkedForOutdate = false;
String[] lines = new String[8]; String[] lines = new String[8];
String[] oldLines = new String[8]; String[] oldLines = new String[8];
DateTime start = DateTime.Now; DateTime start = DateTime.Now;
Utilities.Wait(1); Utilities.Wait(1);
#if DEBUG == false
Broadcast("IW4M Admin is now ^2ONLINE"); Broadcast("IW4M Admin is now ^2ONLINE");
#endif
while (errors <=5) while (errors <=5)
{ {
#if DEBUG == false
try try
#endif
{ {
lastMessage = DateTime.Now - start; lastMessage = DateTime.Now - start;
if(lastMessage.TotalSeconds > messageTime && messages.Count > 0) if(lastMessage.TotalSeconds > messageTime && messages.Count > 0)
{ {
if (RCON.responseSendRCON("sv_online") == null) if (RCON.addRCON("sv_online") == null)
{ {
timesFailed++; timesFailed++;
Log.Write("Server appears to be offline - " + timesFailed, Log.Level.Debug); Log.Write("Server appears to be offline - " + timesFailed, Log.Level.Debug);
@ -381,7 +423,7 @@ namespace IW4MAdmin
else else
timesFailed = 0; timesFailed = 0;
Thread.Sleep(300); Thread.Sleep(300);
initMacros(); initMacros(); // somethings dynamically change so we have to re-init the dictionary
Broadcast(Utilities.processMacro(Macros, messages[nextMessage])); Broadcast(Utilities.processMacro(Macros, messages[nextMessage]));
if (nextMessage == (messages.Count - 1)) if (nextMessage == (messages.Count - 1))
nextMessage = 0; nextMessage = 0;
@ -390,6 +432,16 @@ namespace IW4MAdmin
start = DateTime.Now; start = DateTime.Now;
if (timesFailed <= 3) if (timesFailed <= 3)
HB.Send(); HB.Send();
String checkVer = new Connection("http://raidmax.org/IW4M/Admin/version.php").Read();
double checkVerNum;
double.TryParse(checkVer, out checkVerNum);
if (checkVerNum != Program.Version && checkVerNum != 0 && !checkedForOutdate)
{
messages.Add("^5IW4M Admin ^7is outdated. Please ^5update ^7to version " + checkVerNum);
checkedForOutdate = true;
}
} }
if (l_size != logFile.getSize()) if (l_size != logFile.getSize())
@ -438,20 +490,38 @@ namespace IW4MAdmin
l_size = logFile.getSize(); l_size = logFile.getSize();
Thread.Sleep(1); Thread.Sleep(1);
} }
#if DEBUG == false
catch (Exception E) catch (Exception E)
{ {
Log.Write("Something unexpected occured. Hopefully we can ignore it - " + E.Message + " @" + Utilities.GetLineNumber(E), Log.Level.All); Log.Write("Something unexpected occured. Hopefully we can ignore it - " + E.Message + " @" + Utilities.GetLineNumber(E), Log.Level.All);
errors++; errors++;
continue; continue;
} }
#endif
} }
isRunning = false;
RCONQueue.Abort(); RCONQueue.Abort();
eventQueue.Abort(); eventQueue.Abort();
} }
private void pollServer()
{
while (isRunning)
{
IPS = Utilities.IPFromStatus(RCON.addRCON("status"));
while (IPS == null)
{
IPS = Utilities.IPFromStatus(RCON.addRCON("status"));
Utilities.Wait(1);
}
lastPoll = DateTime.Now;
Utilities.Wait(15);
}
}
//Vital RCON commands to establish log file and server name. May need to cleanup in the future //Vital RCON commands to establish log file and server name. May need to cleanup in the future
private bool intializeBasics() private bool intializeBasics()
{ {
@ -513,7 +583,7 @@ namespace IW4MAdmin
//END //END
//get fs_game //get fs_game
p =RCON.addRCON("fs_game"); p = RCON.addRCON("fs_game");
if (p == null) if (p == null)
{ {
@ -550,7 +620,7 @@ namespace IW4MAdmin
//END //END
//get g_logsync //get g_logsync
p =RCON.addRCON("g_logsync"); p = RCON.addRCON("g_logsync");
if (p == null) if (p == null)
{ {
@ -596,7 +666,7 @@ namespace IW4MAdmin
Log.Write("Log file is " + logPath, Log.Level.Debug); Log.Write("Log file is " + logPath, Log.Level.Debug);
//get players ip's //get players ip's
p =RCON.addRCON("status"); p = RCON.addRCON("status");
if (p == null) if (p == null)
{ {
Log.Write("Unable to get initial player list!", Log.Level.Debug); Log.Write("Unable to get initial player list!", Log.Level.Debug);
@ -604,6 +674,7 @@ namespace IW4MAdmin
} }
IPS = Utilities.IPFromStatus(p); IPS = Utilities.IPFromStatus(p);
lastPoll = DateTime.Now;
#if DEBUG #if DEBUG
/* System.Net.FtpWebRequest tmp = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create("ftp://raidmax.org/logs/games_old.log"); /* System.Net.FtpWebRequest tmp = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create("ftp://raidmax.org/logs/games_old.log");
@ -612,7 +683,6 @@ namespace IW4MAdmin
String ftpLog = new StreamReader(ftpStream).ReadToEnd();*/ String ftpLog = new StreamReader(ftpStream).ReadToEnd();*/
logPath = "games_old.log"; logPath = "games_old.log";
#endif #endif
return true; return true;
} }
catch (Exception E) catch (Exception E)
@ -978,6 +1048,8 @@ namespace IW4MAdmin
//Will probably move this later //Will probably move this later
private Dictionary<String, String> IPS; private Dictionary<String, String> IPS;
public bool isRunning;
private DateTime lastPoll;
//Log stuff //Log stuff

View File

@ -113,6 +113,9 @@ namespace IW4MAdmin
{ {
Dictionary<String, String> Dict = new Dictionary<String, String>(); Dictionary<String, String> Dict = new Dictionary<String, String>();
if (players == null)
return null;
foreach (String S in players) foreach (String S in players)
{ {
String S2 = S.Trim(); String S2 = S.Trim();
@ -141,5 +144,47 @@ namespace IW4MAdmin
string dateTimeFormat = "{0}-{1}-{2} {3}:{4}:{5}.{6}"; string dateTimeFormat = "{0}-{1}-{2} {3}:{4}:{5}.{6}";
return string.Format(dateTimeFormat, datetime.Year, datetime.Month, datetime.Day, datetime.Hour, datetime.Minute, datetime.Second, datetime.Millisecond); return string.Format(dateTimeFormat, datetime.Year, datetime.Month, datetime.Day, datetime.Hour, datetime.Minute, datetime.Second, datetime.Millisecond);
} }
public static String timesConnected(int connection)
{
String Prefix = String.Empty;
if (connection % 10 > 3 || connection % 10 == 0)
Prefix = "th";
else
{
switch (connection % 10)
{
case 1:
Prefix = "st";
break;
case 2:
Prefix = "nd";
break;
case 3:
Prefix = "rd";
break;
}
}
switch (connection)
{
case 0:
case 1:
return "first";
case 2:
return "second";
case 3:
return "third";
case 4:
return "fourth";
case 5:
return "fifth";
case 100:
return "One-Hundreth (amazing!)";
default:
return connection.ToString() + Prefix;
}
}
} }
} }

View File

@ -1,11 +1,4 @@
VERSION: 0.5 VERSION: 0.6
CHANGELOG: CHANGELOG:
-close config files after reading oops -stability fixes
-added reload command -welcome has post-fixed connection indicator
-added macros! (Denoted by {{MACRO}} in server config right now only {{WISDOM}} and {{TOTALPLAYERS}})
-added IP's (tracks and rebans new accounts on same banned ip)!
-aliases
-reworked database classes
-heartbeat gives running version
-player banned in find gives last ban reason
-reworked rcon yet again