Intial Commit of Version 0.1

This commit is contained in:
RaidMax 2015-03-08 16:20:10 -05:00
commit 3d366e6522
23 changed files with 2940 additions and 0 deletions

189
.gitignore vendored Normal file
View File

@ -0,0 +1,189 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
x64/
build/
bld/
[Bb]in/
[Oo]bj/
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
## TODO: Comment the next line if you want to checkin your
## web deploy settings but do note that will include unencrypted
## passwords
#*.pubxml
# NuGet Packages Directory
packages/*
## TODO: If the tool you use requires repositories.config
## uncomment the next line
#!packages/repositories.config
# Enable "build/" folder in the NuGet Packages folder since
# NuGet packages use it for MSBuild targets.
# This line needs to be after the ignore of the build folder
# (and the packages folder if the line above has been uncommented)
!packages/build/
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml

BIN
Admin/4D1.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

29
Admin/Admin.cs Normal file
View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IW4MAdmin
{
class Admin
{
public Admin()
{
Time = DateTime.Now;
Server = new Server("127.0.0.1", 28960, "NO");
}
public Server Server;
public static String getTime()
{
return DateTime.Now.ToString("H:mm:ss");
}
public void Monitor()
{
Server.Monitor();
}
private DateTime Time;
}
}

6
Admin/App.config Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v2.0.50727"/></startup>
</configuration>

39
Admin/Bans.cs Normal file
View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IW4MAdmin
{
class Ban
{
public Ban(String Reas, String TargID, String From)
{
Reason = Reas;
npID = TargID;
bannedByID = From;
When = DateTime.Now;
}
public String getReason()
{
return Reason;
}
public String getID()
{
return npID;
}
public String getBanner()
{
return bannedByID;
}
private String Reason;
private String npID;
private String bannedByID;
private DateTime When;
}
}

431
Admin/Command.cs Normal file
View File

@ -0,0 +1,431 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IW4MAdmin
{
abstract class Command
{
public Command(String N, String D, String U, Player.Permission P, int args, bool nT)
{
Name = N;
Description = D;
Usage = U;
Permission = P;
Arguments = args;
hasTarget = nT;
}
//Get command name
public String getName()
{
return Name;
}
//Get description on command
public String getDescription()
{
return Description;
}
//Get the example usage of the command
public String getAlias()
{
return Usage;
}
//Get the required permission to execute the command
public Player.Permission getNeededPerm()
{
return Permission;
}
public int getNumArgs()
{
return Arguments;
}
public bool needsTarget()
{
return hasTarget;
}
//Execute the command
abstract public void Execute(Event E);
private String Name;
private String Description;
private String Usage;
private int Arguments;
private bool hasTarget;
public Player.Permission Permission;
}
class Owner : Command
{
public Owner(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
if (E.Owner.owner == null)
{
E.Origin.setLevel(Player.Permission.Owner);
E.Origin.Tell("Congratulations, you have claimed ownership of this server!");
E.Owner.owner = E.Origin;
E.Owner.DB.updatePlayer(E.Origin);
}
else
E.Origin.Tell("This server already has an owner!");
}
}
class Warn : Command
{
public Warn(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
if (E.Origin.getLevel() <= E.Target.getLevel())
E.Origin.Tell("You cannot warn " + E.Target.getName());
else
{
E.Target.LastOffense = Utilities.removeWords(E.Data, 1);
E.Target.Warnings++;
String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", E.Target.Warnings, E.Target.getName(), E.Target.LastOffense);
E.Owner.Broadcast(Message);
if (E.Target.Warnings >= 4)
E.Target.Kick("You were kicked for too many warnings!");
}
}
}
class WarnClear : Command
{
public WarnClear(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Target.LastOffense = String.Empty;
E.Target.Warnings = 0;
String Message = String.Format("All warning cleared for {0}", E.Target.getName());
E.Owner.Broadcast(Message);
}
}
class Kick : Command
{
public Kick(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Target.LastOffense = Utilities.removeWords(E.Data, 1);
String Message = "^1Player Kicked: ^5" + E.Target.LastOffense + " ^1Admin: ^5" + E.Origin.getName();
if (E.Origin.getLevel() > E.Target.getLevel())
E.Target.Kick(Message);
else
E.Origin.Tell("You cannot kick " + E.Target.getName());
}
}
class Say : Command
{
public Say(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Owner.Broadcast("^1" + E.Origin.getName() + " - ^6" + E.Data + "^7");
}
}
class TempBan : Command
{
public TempBan(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Target.LastOffense = Utilities.removeWords(E.Data, 1);
String Message = "^1Player Temporarily Banned: ^5" + E.Target.LastOffense + "^7 (1 hour)";
if (E.Origin.getLevel() > E.Target.getLevel())
E.Target.tempBan(Message);
else
E.Origin.Tell("You cannot temp ban " + E.Target.getName());
}
}
class SBan : Command
{
public SBan(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Target.LastOffense = Utilities.removeWords(E.Data, 1);
E.Target.lastEvent = E; // needs to be fixed
String Message = "^1Player Banned: ^5" + E.Target.LastOffense + "^7 (appeal at nbsclan.org)";
if (E.Origin.getLevel() > E.Target.getLevel())
E.Target.Ban(Message, E.Origin);
else
E.Origin.Tell("You cannot ban " + E.Target.getName());
}
}
class Unban : Command
{
public Unban(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
if (E.Owner.Unban(E.Data.Trim()))
E.Origin.Tell("Successfully unbanned " + E.Data.Trim());
else
E.Origin.Tell("Unable to find a ban for that GUID");
}
}
class WhoAmI : Command
{
public WhoAmI(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
String You = String.Format("You are {0} at client spot {1} with xuid {2}. You have connected {3} times and are currently ranked {4}", E.Origin.getName(), E.Origin.getClientNum(), E.Origin.getID(), E.Origin.getConnections(), E.Origin.getLevel());
E.Origin.Tell(You);
}
}
class List : Command
{
public List(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
foreach (Player P in E.Owner.getPlayers())
{
if (P == null)
continue;
E.Origin.Tell(String.Format("[^3{0}^7]{3}[^3{1}^7] {2}", P.getLevel(), P.getClientNum(), P.getName(), Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.getLevel().ToString().Length)));
}
}
}
class Help : Command
{
public Help(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
String cmd = E.Data.Trim();
if (cmd.Length > 2)
{
bool found = false;
foreach (Command C in E.Owner.getCommands())
{
if (C.getName().Contains(cmd) || C.getName() == cmd)
{
E.Origin.Tell(" [^3" + C.getName() + "^7] " + C.getDescription());
found = true;
}
}
if (!found)
E.Origin.Tell("Could not find that command");
}
else
{
foreach (Command C in E.Owner.getCommands())
{
if (E.Origin.getLevel() >= C.getNeededPerm())
{
E.Origin.Tell(" [^3" + C.getName() + "^7] ");
}
}
E.Origin.Tell("Type !help <cmd> to get command usage example");
}
}
}
class FastRestart : Command
{
public FastRestart(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Owner.Broadcast("Performing fast restart in 5 seconds...");
E.Owner.fastRestart(5);
}
}
class MapRotate : Command
{
public MapRotate(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Owner.Broadcast("Performing map rotate in 5 seconds...");
E.Owner.mapRotate(5);
}
}
class SetLevel : Command
{
public SetLevel(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
if (E.Target == E.Origin)
{
E.Origin.Tell("You can't set your own level, silly.");
return;
}
Player.Permission newPerm = Utilities.matchPermission(Utilities.removeWords(E.Data, 1));
if (newPerm > Player.Permission.Banned)
{
E.Target.setLevel(newPerm);
E.Target.Tell("Congratulations! You have been promoted to ^3" + newPerm);
E.Origin.Tell(E.Target.getName() + " was successfully promoted!");
//NEEED TO mOVE
E.Owner.DB.updatePlayer(E.Target);
}
else
E.Origin.Tell("Invalid group specified.");
}
}
class Usage : Command
{
public Usage(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
E.Origin.Tell("IW4M Admin is using " + Math.Round(((System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / 2048f) / 1200f), 1) + "MB");
}
}
class Uptime : Command
{
public Uptime(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
TimeSpan uptime = DateTime.Now - System.Diagnostics.Process.GetCurrentProcess().StartTime;
E.Origin.Tell(String.Format("IW4M Admin has been up for {0} days, {1} hours, and {2} minutes", uptime.Days, uptime.Hours, uptime.Minutes));
}
}
class Admins : Command
{
public Admins(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
foreach (Player P in E.Owner.getPlayers())
{
if (P != null && P.getLevel() > Player.Permission.User)
{
E.Origin.Tell(String.Format("[^3{0}^7]{3}[^3{1}^7] {2}", P.getLevel(), P.getClientNum(), P.getName(), Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.getLevel().ToString().Length)));
}
}
}
}
class Wisdom : Command
{
public Wisdom(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
String Quote = new Connection("http://www.iheartquotes.com/api/v1/random?max_lines=1&max_characters=200").Read();
E.Owner.Broadcast(Utilities.removeNastyChars(Quote));
}
}
class MapCMD : Command
{
public MapCMD(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
string newMap = E.Data.Trim().ToLower();
foreach (Map m in E.Owner.maps)
{
if (m.Name.ToLower() == newMap || m.Alias.ToLower() == newMap)
{
E.Owner.Broadcast("Changing to map ^2" + m.Alias);
Utilities.Wait(3);
E.Owner.Map(m.Name);
return;
}
}
E.Owner.Broadcast("Attempting to change to unknown map ^1" + newMap);
Utilities.Wait(3);
E.Owner.Map(newMap);
}
}
class Find : Command
{
public Find(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
var db_players = E.Owner.DB.findPlayers(E.Data.Trim());
if (db_players == null)
{
E.Origin.Tell("No players found");
return;
}
foreach (Player P in db_players)
{
String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - {2}", P.getName(), P.getDBID(), P.getID());
E.Origin.Tell(mesg);
}
}
}
class Rules : Command
{
public Rules(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override void Execute(Event E)
{
if (E.Owner.rules.Count < 1)
E.Origin.Tell("This server has not set any rules.");
else
{
foreach (String r in E.Owner.rules)
E.Origin.Tell("- " + r);
}
}
}
}

33
Admin/Connection.cs Normal file
View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
namespace IW4MAdmin
{
class Connection
{
public Connection(String Loc)
{
Location = Loc;
ConnectionHandle = WebRequest.Create(Location);
ConnectionHandle.Proxy = null;
}
public String Read()
{
WebResponse Resp = ConnectionHandle.GetResponse();
StreamReader data_in = new StreamReader(Resp.GetResponseStream());
String result = data_in.ReadToEnd();
data_in.Close();
Resp.Close();
return result;
}
private String Location;
private WebRequest ConnectionHandle;
}
}

244
Admin/Database.cs Normal file
View File

@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SQLite;
using System.Data;
using System.IO;
using System.Collections;
namespace IW4MAdmin
{
class Database
{
public Database(String FN)
{
FileName = FN;
DBCon = String.Format("Data Source={0}", FN);
Con = new SQLiteConnection(DBCon);
Init();
}
private void Init()
{
if(!File.Exists(FileName))
{
String query = "CREATE TABLE [CLIENTS] ( [Name] TEXT NULL, [npID] TEXT NULL, [Number] INTEGER PRIMARY KEY AUTOINCREMENT, [Level] INT DEFAULT 0 NULL, [LastOffense] TEXT NULL, [Connections] INT DEFAULT 1 NULL);";
ExecuteNonQuery(query);
query = "CREATE TABLE [BANS] ( [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] Text NULL)";
ExecuteNonQuery(query);
}
}
public Player getPlayer(String ID, int cNum)
{
String Query = String.Format("SELECT * FROM CLIENTS WHERE npID = '{0}' LIMIT 1", ID);
DataTable Result = GetDataTable(Query);
if (Result != null && Result.Rows.Count > 0)
{
DataRow ResponseRow = Result.Rows[0];
return new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), cNum, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), ResponseRow["LastOffense"].ToString(), ((int)ResponseRow["Connections"] + 1));
}
else
return null;
}
public List<Player> findPlayers(String name)
{
String Query = String.Format("SELECT * FROM CLIENTS WHERE Name LIKE '%{0}%' LIMIT 10", name);
DataTable Result = GetDataTable(Query);
List<Player> Players = new List<Player>();
if (Result != null && Result.Rows.Count > 0)
{
foreach (DataRow p in Result.Rows)
{
Players.Add(new Player(p["Name"].ToString(), p["npID"].ToString(), -1, (Player.Permission)(p["Level"]), Convert.ToInt32(p["Number"]), p["LastOffense"].ToString(), ((int)p["Connections"])));
}
return Players;
}
else
return null;
}
public Player findPlayers(int dbIndex)
{
String Query = String.Format("SELECT * FROM CLIENTS WHERE Number = '{0}' LIMIT 1", dbIndex);
DataTable Result = GetDataTable(Query);
if (Result != null && Result.Rows.Count > 0)
{
foreach (DataRow p in Result.Rows)
return new Player(p["Name"].ToString(), p["npID"].ToString(), -1, (Player.Permission)(p["Level"]), Convert.ToInt32(p["Number"]), p["LastOffense"].ToString(), ((int)p["Connections"]));
}
return null;
}
public Player getOwner()
{
String Query = String.Format("SELECT * FROM CLIENTS WHERE Level = '{0}'", 4);
DataTable Result = GetDataTable(Query);
if (Result != null && Result.Rows.Count > 0)
{
DataRow ResponseRow = Result.Rows[0];
return new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), -1, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), null, 0);
}
else
return null;
}
public List<Ban> getBans()
{
List<Ban> Bans = new List<Ban>();
DataTable Result = GetDataTable("SELECT * FROM BANS");
foreach (DataRow Row in Result.Rows)
Bans.Add(new Ban(Row["Reason"].ToString(), Row["npID"].ToString(), Row["bannedByID"].ToString()));
return Bans;
}
public void removeBan(String GUID)
{
String Query = String.Format("DELETE FROM BANS WHERE npID = '{0}'", GUID);
ExecuteNonQuery(Query);
}
public void addPlayer(Player P)
{
Dictionary<String, object> newPlayer = new Dictionary<String, object>();
newPlayer.Add("Name", Utilities.removeNastyChars(P.getName()));
newPlayer.Add("npID", P.getID());
newPlayer.Add("Level", (int)P.getLevel());
// newPlayer.Add("Number", P.getClientNum().ToString());
newPlayer.Add("LastOffense", "");
newPlayer.Add("Connections", 1);
Insert("CLIENTS", newPlayer);
}
public void updatePlayer(Player P)
{
Dictionary<String, object> updatedPlayer = new Dictionary<String, object>();
updatedPlayer.Add("Name", P.getName());
updatedPlayer.Add("npID", P.getID());
updatedPlayer.Add("Level", (int)P.getLevel());
// updatedPlayer.Add("Number", P.getClientNum().ToString());
updatedPlayer.Add("LastOffense", P.getLastO());
updatedPlayer.Add("Connections", P.getConnections());
Update("CLIENTS", updatedPlayer, String.Format("npID = '{0}'", P.getID()));
}
public void addBan(Ban B)
{
Dictionary<String, object> newBan = new Dictionary<String, object>();
newBan.Add("Reason", B.getReason());
newBan.Add("npID", B.getID());
newBan.Add("bannedByID", B.getBanner());
Insert("BANS", newBan);
}
//HELPERS
public bool Insert(String tableName, Dictionary<String, object> data)
{
String columns = "";
String values = "";
Boolean returnCode = true;
foreach (KeyValuePair<String, object> val in data)
{
columns += String.Format(" {0},", val.Key);
values += String.Format(" '{0}',", val.Value);
}
columns = columns.Substring(0, columns.Length - 1);
values = values.Substring(0, values.Length - 1);
try
{
this.ExecuteNonQuery(String.Format("insert into {0}({1}) values({2});", tableName, columns, values));
}
catch (Exception fail)
{
Console.WriteLine(fail.Message);
returnCode = false;
}
return returnCode;
}
public bool Update(String tableName, Dictionary<String, object> data, String where)
{
String vals = "";
Boolean returnCode = true;
if (data.Count >= 1)
{
foreach (KeyValuePair<String, object> val in data)
{
vals += String.Format(" {0} = '{1}',", val.Key, val.Value);
}
vals = vals.Substring(0, vals.Length - 1);
}
try
{
this.ExecuteNonQuery(String.Format("update {0} set {1} where {2};", tableName, vals, where));
}
catch (Exception fail)
{
Console.WriteLine(fail.Message);
returnCode = false;
}
return returnCode;
}
public DataRow getDataRow(String Q)
{
DataRow Result = GetDataTable(Q).Rows[0];
return Result;
}
private int ExecuteNonQuery(String Request)
{
Con.Open();
SQLiteCommand CMD = new SQLiteCommand(Con);
CMD.CommandText = Request;
int rowsUpdated = CMD.ExecuteNonQuery();
Con.Close();
return rowsUpdated;
}
public DataTable GetDataTable(String sql)
{
DataTable dt = new DataTable();
try
{
Con.Open();
SQLiteCommand mycommand = new SQLiteCommand(Con);
mycommand.CommandText = sql;
SQLiteDataReader reader = mycommand.ExecuteReader();
dt.Load(reader);
reader.Close();
Con.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw new Exception(e.Message);
}
return dt;
}
//END
private String FileName;
private String DBCon;
private SQLiteConnection Con;
}
}

105
Admin/Event.cs Normal file
View File

@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace IW4MAdmin
{
class Event
{
public enum GType
{
//FROM SERVER
Connect,
Disconnect,
Say,
Kill,
Death,
MapChange,
MapEnd,
//FROM ADMIN
Broadcast,
Tell,
Kick,
Ban,
Unknown,
}
public Event(GType t, string d, Player O, Player T, Server S)
{
Type = t;
Data = d;
Origin = O;
Target = T;
Owner = S;
}
//This needs to be here
public Command isValidCMD(List<Command> list)
{
if (this.Data.Substring(0, 1) == "!")
{
string[] cmd = this.Data.Substring(1, this.Data.Length - 1).Split(' ');
foreach (Command C in list)
{
if (C.getName() == cmd[0].ToLower() || C.getAlias() == cmd[0].ToLower())
return C;
}
return null;
}
else
return null;
}
public static Event requestEvent(String[] line, Server SV)
{
try
{
String eventType = line[0].Substring(line[0].Length - 1);
eventType = eventType.Trim();
if (eventType == "J")
return new Event(GType.Connect, null, SV.clientFromLine(line, 3, true), null, SV);
if (eventType == "Q")
return new Event(GType.Disconnect, null, SV.clientFromLine(line, 3, false), null, null);
if (line[0].Substring(line[0].Length - 3).Trim() == "say")
{
Regex rgx = new Regex("[^a-zA-Z0-9 -! -_]");
string message = rgx.Replace(line[4], "");
if (message.Length < 2)
message = " ";
return new Event(GType.Say, Utilities.removeNastyChars(message), SV.clientFromLine(line, 3, false), null, null);
}
if (eventType == "d")
return new Event(GType.MapEnd, null, null, null, null);
if (line[0].Length > 400) // blaze it
return new Event(GType.MapChange, null, null, null, null);
return null;
}
catch (Exception E)
{
SV.Log.Write("Error requesting event " + E.Message, Log.Level.Debug);
return null;
}
}
public GType Type;
public string Data; // Data is usually the message sent by player
public Player Origin;
public Player Target;
public Server Owner;
}
}

161
Admin/File.cs Normal file
View File

@ -0,0 +1,161 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace IW4MAdmin
{
class file
{
public file(String fileName)
{
//Not safe for directories with more than one folder but meh
_Directory = fileName.Split('\\')[0];
Name = (fileName.Split('\\'))[fileName.Split('\\').Length-1];
if (!Directory.Exists(_Directory))
Directory.CreateDirectory(_Directory);
if (!File.Exists(fileName))
{
FileStream penis = File.Create(fileName);
penis.Close();
}
Handle = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
sze = Handle.BaseStream.Length;
}
public file(String file, bool write)
{
Name = file;
writeHandle = new StreamWriter(new FileStream(Name, FileMode.Create, FileAccess.Write, FileShare.ReadWrite));
sze = 0;
}
public long getSize()
{
sze = Handle.BaseStream.Length;
return sze;
}
public void Write(String line)
{
writeHandle.WriteLine(line);
writeHandle.Flush();
}
public String[] getParameters(int num)
{
if (sze > 0)
{
String firstLine = Handle.ReadLine();
String[] Parms = firstLine.Split(':');
if (Parms.Length < num)
return null;
else
return Parms;
}
return null;
}
public int getNumLines()
{
return 0;
}
//FROM http://stackoverflow.com/questions/398378/get-last-10-lines-of-very-large-text-file-10gb-c-sharp
public string ReadEndTokens()
{
Encoding encoding = Encoding.ASCII;
string tokenSeparator = "\n";
int numberOfTokens = 2;
int sizeOfChar = encoding.GetByteCount("\n");
byte[] buffer = encoding.GetBytes(tokenSeparator);
using (FileStream fs = new FileStream(this.Name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
Int64 tokenCount = 0;
Int64 endPosition = fs.Length / sizeOfChar;
for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar)
{
fs.Seek(-position, SeekOrigin.End);
fs.Read(buffer, 0, buffer.Length);
if (encoding.GetString(buffer) == tokenSeparator)
{
tokenCount++;
if (tokenCount == numberOfTokens)
{
byte[] returnBuffer = new byte[fs.Length - fs.Position];
fs.Read(returnBuffer, 0, returnBuffer.Length);
return encoding.GetString(returnBuffer);
}
}
}
// handle case where number of tokens in file is less than numberOfTokens
fs.Seek(0, SeekOrigin.Begin);
buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
return encoding.GetString(buffer);
}
}
public String[] readAll()
{
return Handle.ReadToEnd().Split('\n');
}
public String[] end(int neededLines)
{
var lines = new List<String>();
while (!Handle.EndOfStream)
{
String lins = Handle.ReadLine();
lines.Add(lins.ToString());
if (lines.Count > neededLines)
{
lines.RemoveAt(0);
}
}
return lines.ToArray();
}
public String[] Tail(int lineCount)
{
var buffer = new List<string>(lineCount);
string line;
for (int i = 0; i < lineCount; i++)
{
line = Handle.ReadLine();
if (line == null) return buffer.ToArray();
buffer.Add(line);
}
int lastLine = lineCount - 1; //The index of the last line read from the buffer. Everything > this index was read earlier than everything <= this indes
while (null != (line = Handle.ReadLine()))
{
lastLine++;
if (lastLine == lineCount) lastLine = 0;
buffer[lastLine] = line;
}
if (lastLine == lineCount - 1) return buffer.ToArray();
var retVal = new string[lineCount];
buffer.CopyTo(lastLine + 1, retVal, 0, lineCount - lastLine - 1);
buffer.CopyTo(0, retVal, lineCount - lastLine - 1, lastLine + 1);
return retVal;
}
//END
private long sze;
private String Name;
private String _Directory;
StreamReader Handle;
StreamWriter writeHandle;
}
}

145
Admin/IW4M ADMIN.csproj Normal file
View File

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DD5DCDA2-51DB-4B1A-922F-5705546E6115}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IW4MAdmin</RootNamespace>
<AssemblyName>IW4MAdmin</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>C:\Users\Michael\Desktop\IW4MAdmin\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ProductName>IW4M Administration</ProductName>
<PublisherName>RaidMax LLC</PublisherName>
<WebPage>publish.htm</WebPage>
<AutorunEnabled>true</AutorunEnabled>
<ApplicationRevision>2</ApplicationRevision>
<ApplicationVersion>0.1.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>0</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>0D02A7F5C6EA170625B5BF533E667AE6C3F93065</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>IW4M ADMIN_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<TargetZone>LocalIntranet</TargetZone>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<SignManifests>true</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>4D1.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>IW4MAdmin.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Release\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Bans.cs" />
<Compile Include="Command.cs" />
<Compile Include="Connection.cs" />
<Compile Include="Database.cs" />
<Compile Include="Event.cs" />
<Compile Include="File.cs" />
<Compile Include="Log.cs" />
<Compile Include="Main.cs" />
<Compile Include="Maps.cs" />
<Compile Include="Player.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="RCON.cs" />
<Compile Include="Server.cs" />
<Compile Include="Utilities.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="IW4M ADMIN_TemporaryKey.pfx" />
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="4D1.ico" />
</ItemGroup>
<ItemGroup>
<Folder Include="Fakes\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

54
Admin/Log.cs Normal file
View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IW4MAdmin
{
class Log
{
public enum Level
{
All,
Debug,
Production,
None,
}
public Log(file logf, Level mode)
{
logFile = logf;
logMode = mode;
}
public void Write(String line, Level lv)
{
String Line = String.Format("{1} - [{0}]: {2}", lv, getTime(), line);
switch(logMode)
{
case Level.All:
if (lv == Level.All || lv == Level.Debug || lv == Level.Production)
Console.WriteLine(Line);
break;
case Level.Debug:
if (lv == Level.All || lv == Level.Debug)
Console.WriteLine(Line);
break;
case Level.Production:
if (lv == Level.Production)
Console.WriteLine(Line);
break;
}
logFile.Write(Line);
}
private string getTime()
{
return DateTime.Now.ToString("HH:mm:ss");
}
private file logFile;
private Level logMode;
}
}

36
Admin/Main.cs Normal file
View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IW4MAdmin
{
class Program
{
static void Main(string[] args)
{
file Config = new file("config\\servers.cfg");
String[] SV_CONF = Config.getParameters(3);
double Version = 0.1;
if (Config.getSize() > 0 && SV_CONF != null)
{
Console.WriteLine("=====================================================");
Console.WriteLine(" IW4M ADMIN v" + Version);
Console.WriteLine(" by RaidMax ");
Console.WriteLine("=====================================================");
Console.WriteLine("Starting admin on port " + SV_CONF[1]);
Server IW4M;
IW4M = new Server(SV_CONF[0], Convert.ToInt32(SV_CONF[1]), SV_CONF[2]);
IW4M.Monitor();
}
else
{
Console.WriteLine("[FATAL] CONFIG FILE DOES NOT EXIST OR IS INCORRECT!");
Utilities.Wait(5);
}
}
}
}

18
Admin/Maps.cs Normal file
View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IW4MAdmin
{
class Map
{
public Map(String N, String A)
{
Name = N;
Alias = A;
}
public String Name;
public String Alias;
}
}

134
Admin/Player.cs Normal file
View File

@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IW4MAdmin
{
class Player
{
public enum Permission
{
Banned = -1,
User = 0,
Moderator = 1,
Administrator = 2,
SeniorAdmin = 3,
Owner = 4,
Creator = 5,
}
public Player(string n, string id, int num, int l)
{
Name = n;
npID = id;
Number = num;
Level = (Player.Permission)l;
LastOffense = null;
Connections = 0;
Warnings = 0;
}
public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con)
{
Name = n;
npID = id;
Number = num;
Level = l;
dbID = cind;
LastOffense = lo;
Connections = con;
Warnings = 0;
}
public String getName()
{
return Name;
}
public String getID()
{
return npID;
}
public String getDBID()
{
return Convert.ToString(dbID);
}
public int getClientNum()
{
return Number;
}
public Player.Permission getLevel()
{
return Level;
}
public int getConnections()
{
return Connections;
}
public String getLastO()
{
return LastOffense;
}
// BECAUSE IT NEEDS TO BE CHANGED!
public void setLevel(Player.Permission Perm)
{
Level = Perm;
}
public void Tell(String Message)
{
lastEvent.Owner.Tell(Message, this);
}
public void Warn(String Message)
{
lastEvent.Owner.Broadcast(Message);
}
public void Kick(String Message)
{
lastEvent.Owner.Kick(Message, this);
}
public void tempBan(String Message)
{
lastEvent.Owner.tempBan(Message, this);
}
public void Ban(String Message, Player Sender)
{
lastEvent.Owner.Ban(Message, this, Sender);
}
//should be moved to utils
public Player findPlayer(String Nme)
{
foreach (Player P in lastEvent.Owner.getPlayers())
{
if (P == null)
continue;
if (P.getName().ToLower().Contains(Name.ToLower()))
return P;
}
return null;
}
private string Name;
private string npID;
private int Number;
private Player.Permission Level;
private int dbID;
private int Connections;
public Event lastEvent;
public String LastOffense;
public int Warnings;
}
}

View File

@ -0,0 +1,37 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IW4M Admin")]
[assembly: AssemblyDescription("Admin for IW4x projects")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("RaidMax LLC")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("© 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("62f47df4-c8eb-4b5d-bdd8-9de0ca6b570f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.*")]
[assembly: NeutralResourcesLanguageAttribute("en")]

View File

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
</SettingsFile>

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel node will disable file and registry virtualization.
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
</applicationRequestMinimum>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of all Windows versions that this application is designed to work with.
Windows will automatically select the most compatible environment.-->
<!-- If your application is designed to work with Windows Vista, uncomment the following supportedOS node-->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
<!-- If your application is designed to work with Windows 8, uncomment the following supportedOS node-->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->
</application>
</compatibility>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->
</asmv1:assembly>

129
Admin/RCON.cs Normal file
View File

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
//DILEMMA -- Seperate intance of RCON for each server or no?
namespace IW4MAdmin
{
class RCON
{
enum Type
{
Query,
Execute,
}
public RCON(Server I)
{
sv_connection = new UdpClient();
sv_connection.Client.SendTimeout = 1000;
sv_connection.Client.ReceiveTimeout = 1000;
Instance = I;
toSend = new Queue<String>();
}
//When we don't care about a response
public bool sendRCON(String message)
{
try
{
String STR_REQUEST = String.Format("ÿÿÿÿrcon {0} {1}", Instance.getPassword(), message);
Byte[] Request_ = Encoding.Unicode.GetBytes(STR_REQUEST);
Byte[] Request = new Byte[Request_.Length / 2];
int count = 0; //This is kinda hacky but Unicode -> ASCII doesn't seem to be working correctly for this.
foreach (Byte b in Request_)
{
if (b != 0)
Request[count / 2] = b;
count++;
}
System.Net.IPAddress IP = System.Net.IPAddress.Parse(Instance.getIP());
IPEndPoint endPoint = new IPEndPoint(IP, Instance.getPort());
sv_connection.Connect(endPoint);
sv_connection.Send(Request, Request.Length);
}
catch (SocketException)
{
Instance.Log.Write("Unable to reach server for sending RCON", Log.Level.Debug);
sv_connection.Close();
return false;
}
return true;
}
//We want to read the reponse
public String[] responseSendRCON(String message)
{
try
{
String STR_REQUEST;
if (message != "getstatus")
STR_REQUEST = String.Format("ÿÿÿÿrcon {0} {1}", Instance.getPassword(), message);
else
STR_REQUEST = String.Format("ÿÿÿÿ getstatus");
Byte[] Request_ = Encoding.Unicode.GetBytes(STR_REQUEST);
Byte[] Request = new Byte[Request_.Length/2];
int count = 0; //This is kinda hacky but Unicode -> ASCII doesn't seem to be working correctly for this.
foreach (Byte b in Request_)
{
if (b != 0)
Request[count/2] = b;
count++;
}
System.Net.IPAddress IP = System.Net.IPAddress.Parse(Instance.getIP());
IPEndPoint endPoint = new IPEndPoint(IP, Instance.getPort());
sv_connection.Connect(endPoint);
sv_connection.Send(Request, Request.Length);
Byte[] receive = sv_connection.Receive(ref endPoint);
int num = int.Parse("0a", System.Globalization.NumberStyles.AllowHexSpecifier);
return System.Text.Encoding.UTF8.GetString(receive).Split((char)num);
}
catch (SocketException)
{
Instance.Log.Write("Unable to reach server for sending RCON", Log.Level.Debug);
sv_connection.Close();
return null;
}
}
public void addRCON(String Message, int delay)
{
toSend.Enqueue(Message);
}
public void ManageRCONQueue()
{
while (true)
{
if (toSend.Count > 0)
{
sendRCON(toSend.Peek());
toSend.Dequeue();
}
Utilities.Wait(0.3);
}
}
private UdpClient sv_connection;
private Server Instance;
private DateTime lastCMD;
private Queue<String> toSend;
}
}

234
Admin/SQLiteDatabase.cs Normal file
View File

@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
namespace IW4MAdmin
{
public class SQLiteDatabase
{
String dbConnection;
/// <summary>
/// Default Constructor for SQLiteDatabase Class.
/// </summary>
public SQLiteDatabase(String file)
{
dbConnection = "Data Source=" + file;
}
/// <summary>
/// Single Param Constructor for specifying the DB file.
/// </summary>
/// <param name="inputFile">The File containing the DB</param>
public SQLiteDatabase(String inputFile)
{
dbConnection = String.Format("Data Source={0}", inputFile);
}
/// <summary>
/// Single Param Constructor for specifying advanced connection options.
/// </summary>
/// <param name="connectionOpts">A dictionary containing all desired options and their values</param>
public SQLiteDatabase(Dictionary<String, String> connectionOpts)
{
String str = "";
foreach (KeyValuePair<String, String> row in connectionOpts)
{
str += String.Format("{0}={1}; ", row.Key, row.Value);
}
str = str.Trim().Substring(0, str.Length - 1);
dbConnection = str;
}
/// <summary>
/// Allows the programmer to run a query against the Database.
/// </summary>
/// <param name="sql">The SQL to run</param>
/// <returns>A DataTable containing the result set.</returns>
public DataTable GetDataTable(string sql)
{
DataTable dt = new DataTable();
try
{
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
SQLiteDataReader reader = mycommand.ExecuteReader();
dt.Load(reader);
reader.Close();
cnn.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw new Exception(e.Message);
}
return dt;
}
/// <summary>
/// Allows the programmer to interact with the database for purposes other than a query.
/// </summary>
/// <param name="sql">The SQL to be run.</param>
/// <returns>An Integer containing the number of rows updated.</returns>
public int ExecuteNonQuery(string sql)
{
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
int rowsUpdated = mycommand.ExecuteNonQuery();
cnn.Close();
return rowsUpdated;
}
/// <summary>
/// Allows the programmer to retrieve single items from the DB.
/// </summary>
/// <param name="sql">The query to run.</param>
/// <returns>A string.</returns>
public string ExecuteScalar(string sql)
{
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
object value = mycommand.ExecuteScalar();
cnn.Close();
if (value != null)
{
return value.ToString();
}
return "";
}
/// <summary>
/// Allows the programmer to easily update rows in the DB.
/// </summary>
/// <param name="tableName">The table to update.</param>
/// <param name="data">A dictionary containing Column names and their new values.</param>
/// <param name="where">The where clause for the update statement.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Update(String tableName, Dictionary<String, String> data, String where)
{
String vals = "";
Boolean returnCode = true;
if (data.Count >= 1)
{
foreach (KeyValuePair<String, String> val in data)
{
vals += String.Format(" {0} = '{1}',", val.Key.ToString(), val.Value.ToString());
}
vals = vals.Substring(0, vals.Length - 1);
}
try
{
this.ExecuteNonQuery(String.Format("update {0} set {1} where {2};", tableName, vals, where));
}
catch( Exception fail)
{
Console.WriteLine(fail.Message);
returnCode = false;
}
return returnCode;
}
/// <summary>
/// Allows the programmer to easily delete rows from the DB.
/// </summary>
/// <param name="tableName">The table from which to delete.</param>
/// <param name="where">The where clause for the delete.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Delete(String tableName, String where)
{
Boolean returnCode = true;
try
{
this.ExecuteNonQuery(String.Format("delete from {0} where {1};", tableName, where));
}
catch (Exception fail)
{
Console.WriteLine(fail.Message);
returnCode = false;
}
return returnCode;
}
/// <summary>
/// Allows the programmer to easily insert into the DB
/// </summary>
/// <param name="tableName">The table into which we insert the data.</param>
/// <param name="data">A dictionary containing the column names and data for the insert.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Insert(String tableName, Dictionary<String, String> data)
{
String columns = "";
String values = "";
Boolean returnCode = true;
foreach (KeyValuePair<String, String> val in data)
{
columns += String.Format(" {0},", val.Key.ToString());
values += String.Format(" '{0}',", val.Value);
}
columns = columns.Substring(0, columns.Length - 1);
values = values.Substring(0, values.Length - 1);
try
{
this.ExecuteNonQuery(String.Format("insert into {0}({1}) values({2});", tableName, columns, values));
}
catch (Exception fail)
{
Console.WriteLine(fail.Message);
returnCode = false;
}
return returnCode;
}
/// <summary>
/// Allows the programmer to easily delete all data from the DB.
/// </summary>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool ClearDB()
{
DataTable tables;
try
{
tables = this.GetDataTable("select NAME from SQLITE_MASTER where type='table' order by NAME;");
foreach (DataRow table in tables.Rows)
{
this.ClearTable(table["NAME"].ToString());
}
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Allows the user to easily clear all data from a specific table.
/// </summary>
/// <param name="table">The name of the table to clear.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool ClearTable(String table)
{
try
{
this.ExecuteNonQuery(String.Format("delete from {0};", table));
return true;
}
catch
{
return false;
}
}
}
}

759
Admin/Server.cs Normal file
View File

@ -0,0 +1,759 @@

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading; //SLEEP
using System.IO;
namespace IW4MAdmin
{
class Server
{
const int FLOOD_TIMEOUT = 300;
public Server(string address, int port, string password)
{
IP = address;
Port = port;
rcon_pass = password;
clientnum = 0;
RCON = new RCON(this);
logFile = new file("admin_" + address + "_" + port + ".log", true);
Log = new Log(logFile, Log.Level.Production);
players = new List<Player>(new Player[18]);
DB = new Database(port + ".db");
Bans = DB.getBans();
owner = DB.getOwner();
maps = new List<Map>();
rules = new List<String>();
messages = new List<String>();
events = new Queue<Event>();
nextMessage = 0;
initCommands();
initMessages();
initMaps();
initRules();
}
//Returns the current server name -- *STRING*
public String getName()
{
return hostname;
}
//Returns current server IP set by `net_ip` -- *STRING*
public String getIP()
{
return IP;
}
//Returns current server port set by `net_port` -- *INT*
public int getPort()
{
return Port;
}
//Returns number of active clients on server -- *INT*
public int getNumPlayers()
{
return clientnum;
}
//Returns the list of commands
public List<Command> getCommands()
{
return commands;
}
public List<Player> getPlayers()
{
return players;
}
public List<Ban> getBans()
{
return Bans;
}
//Performs update on server statistics read from log.
public void Update()
{
}
//Add player object p to `players` list
public bool addPlayer(Player P)
{
try
{
if (DB.getPlayer(P.getID(), P.getClientNum()) == null)
DB.addPlayer(P);
else
{
//messy way to prevent loss of last event
Player A;
A = DB.getPlayer(P.getID(), P.getClientNum());
A.lastEvent = P.lastEvent;
P = A;
}
players[P.getClientNum()] = null;
players[P.getClientNum()] = P;
clientnum++;
if (P.getLevel() == Player.Permission.Banned)
{
Log.Write("Banned client " + P.getName() + " trying to connect...", Log.Level.Production);
String Message = "^1Player Kicked: ^7Previously Banned for ^5" + isBanned(P).getReason();
P.Kick(Message);
}
else
Log.Write("Client " + P.getName() + " connecting...", Log.Level.Production);
return true;
}
catch (Exception E)
{
Log.Write("Unable to add player - " + E.Message, Log.Level.Debug);
return false;
}
}
//Remove player by CLIENT NUMBER
public bool removePlayer(int cNum)
{
Log.Write("Client at " + cNum + " disconnecting...", Log.Level.Production);
players[cNum] = null;
clientnum--;
return true;
}
public Player clientFromLine(String[] line, int name_pos, bool create)
{
string Name = line[name_pos].ToString().Trim();
if (create)
{
Player C = new Player(Name, line[1].ToString(), Convert.ToInt16(line[2]), 0);
return C;
}
else
{
foreach (Player P in players)
{
if (P == null)
continue;
if (line[1].Trim() == P.getID())
return P;
}
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));
return players[Convert.ToInt16(line[2])];
}
}
public Player clientFromLine(String Name)
{
foreach (Player P in players)
{
if (P == null)
continue;
if (P.getName().ToLower().Contains(Name.ToLower()))
return P;
}
return null;
}
public Ban isBanned(Player C)
{
if (C.getLevel() == Player.Permission.Banned)
{
foreach (Ban B in Bans)
{
if (B.getID() == C.getID())
return B;
}
}
return null;
}
public Command processCommand(Event E, Command C)
{
E.Data = Utilities.removeWords(E.Data, 1);
String[] Args = E.Data.Trim().Split(' ');
if (Args.Length < (C.getNumArgs()))
{
E.Origin.Tell("Not enough arguments supplied!");
return null;
}
if(E.Origin.getLevel() < C.getNeededPerm())
{
E.Origin.Tell("You do not have access to that command!");
return null;
}
if (C.needsTarget())
{
int cNum = -1;
int.TryParse(Args[0], out cNum);
if (Args[0][0] == '@')
{
int dbID = -1;
int.TryParse(Args[0].Substring(1, Args[0].Length-1), out dbID);
Player found = E.Owner.DB.findPlayers(dbID);
if (found != null)
E.Target = found;
}
else if(Args[0].Length < 3 && cNum > -1 && cNum < 18)
{
if (players[cNum] != null)
E.Target = players[cNum];
}
else
E.Target = clientFromLine(Args[0]);
if (E.Target == null)
{
E.Origin.Tell("Unable to find specified player.");
return null;
}
}
return C;
}
private void addEvent(Event E)
{
events.Enqueue(E);
}
private void manageEventQueue()
{
while (true)
{
if (events.Count > 0)
{
processEvent(events.Peek());
events.Dequeue();
}
Utilities.Wait(0.1);
}
}
//Starts the monitoring process
public void Monitor()
{
if (!intializeBasics())
{
Log.Write("Shutting due to uncorrectable errors..." + logPath, Log.Level.Debug);
Utilities.Wait(10);
Environment.Exit(-1);
}
//Handles new rcon requests in a fashionable manner
Thread RCONQueue = new Thread(new ThreadStart(RCON.ManageRCONQueue));
RCONQueue.Start();
//Handles new events in a fashionable manner
Thread eventQueue = new Thread(new ThreadStart(manageEventQueue));
eventQueue.Start();
long l_size = -1;
String[] lines = new String[8];
String[] oldLines = new String[8];
DateTime start = DateTime.Now;
Utilities.Wait(1);
Broadcast("IW4M Admin is now ^2ONLINE");
while (errors <=5)
{
try
{
lastMessage = DateTime.Now - start;
if(lastMessage.TotalSeconds > messageTime && messages.Count > 0)
{
Broadcast(messages[nextMessage]);
if (nextMessage == (messages.Count - 1))
nextMessage = 0;
else
nextMessage++;
start = DateTime.Now;
}
if (l_size != logFile.getSize())
{
lines = logFile.Tail(8);
if (lines != oldLines)
{
l_size = logFile.getSize();
int end;
if (lines.Length == oldLines.Length)
end = lines.Length - 1;
else
end = Math.Abs((lines.Length - oldLines.Length)) - 1;
for (int count = 0; count < lines.Length; count++)
{
if (lines.Length < 1 && oldLines.Length < 1)
continue;
if (lines[count] == oldLines[oldLines.Length - 1])
continue;
if (lines[count].Length < 10) //Not a needed line
continue;
else
{
string[] game_event = lines[count].Split(';');
Event event_ = Event.requestEvent(game_event, this);
if (event_ != null)
{
if (event_.Origin == null)
event_.Origin = new Player("WORLD", "-1", -1, 0);
event_.Origin.lastEvent = event_;
event_.Origin.lastEvent.Owner = this;
addEvent(event_);
}
}
}
}
}
oldLines = lines;
l_size = logFile.getSize();
Thread.Sleep(1);
}
catch (Exception E)
{
Log.Write("Something unexpected occured. Hopefully we can ignore it - " + E.Message + " @" + Utilities.GetLineNumber(E), Log.Level.All);
errors++;
continue;
}
}
RCONQueue.Abort();
eventQueue.Abort();
}
private bool intializeBasics()
{
try
{
//GET fs_basepath
String[] p = RCON.responseSendRCON("fs_basepath");
if (p == null)
{
Log.Write("Could not obtain basepath!", Log.Level.All);
return false;
}
p = p[1].Split('"');
Basepath = p[3].Substring(0, p[3].Length - 2).Trim();
p = null;
Thread.Sleep(FLOOD_TIMEOUT);
//END
//get fs_game
p = RCON.responseSendRCON("fs_game");
if (p == null)
{
Log.Write("Could not obtain mod path!", Log.Level.All);
return false;
}
p = p[1].Split('"');
Mod = p[3].Substring(0, p[3].Length - 2).Trim().Replace('/', '\\');
p = null;
Thread.Sleep(FLOOD_TIMEOUT);
//END
//get g_log
p = RCON.responseSendRCON("g_log");
if (p == null)
{
Log.Write("Could not obtain log path!", Log.Level.All);
return false;
}
if (p.Length < 4)
{
Thread.Sleep(FLOOD_TIMEOUT);
Log.Write("Server does not appear to have map loaded. Please map_rotate", Log.Level.All);
return false;
}
p = p[1].Split('"');
string log = p[3].Substring(0, p[3].Length - 2).Trim();
p = null;
Thread.Sleep(FLOOD_TIMEOUT);
//END
//get g_logsync
p = RCON.responseSendRCON("g_logsync");
if (p == null)
{
Log.Write("Could not obtain log sync status!", Log.Level.All);
return false;
}
p = p[1].Split('"');
int logsync = Convert.ToInt32(p[3].Substring(0, p[3].Length - 2).Trim());
p = null;
Thread.Sleep(FLOOD_TIMEOUT);
if (logsync != 1)
RCON.sendRCON("g_logsync 1");
Thread.Sleep(FLOOD_TIMEOUT);
//END
//get iw4m_onelog
p = RCON.responseSendRCON("iw4m_onelog");
if (p[0] == String.Empty || p[1].Length < 15)
{
Log.Write("Could not obtain iw4m_onelog value!", Log.Level.All);
return false;
}
p = p[1].Split('"');
string onelog = p[3].Substring(0, p[3].Length - 2).Trim();
p = null;
//END
Thread.Sleep(FLOOD_TIMEOUT);
//get sv_hostname
p = RCON.responseSendRCON("sv_hostname");
if (p == null)
{
Log.Write("Could not obtain server name!", Log.Level.All);
return false;
}
p = p[1].Split('"');
hostname = p[3].Substring(0, p[3].Length - 2).Trim();
p = null;
//END
if (Mod == String.Empty || onelog == "1")
logPath = Basepath + '\\' + "m2demo" + '\\' + log;
else
logPath = Basepath + '\\' + Mod + '\\' + log;
if (!File.Exists(logPath))
{
Log.Write("Gamelog does not exist!", Log.Level.All);
return false;
}
logFile = new file(logPath);
Log.Write("Log file is " + logPath, Log.Level.Debug);
return true;
}
catch (Exception E)
{
Log.Write("Error during initialization - " + E.Message, Log.Level.All);
return false;
}
}
//Process any server event
public bool processEvent(Event E)
{
if (E.Type == Event.GType.Connect)
{
this.addPlayer(E.Origin);
return true;
}
if (E.Type == Event.GType.Disconnect)
{
if (getNumPlayers() > 0)
removePlayer(E.Origin.getClientNum());
return true;
}
if (E.Type == Event.GType.Say)
{
Log.Write("Message from " + E.Origin.getName() + ": " + E.Data, Log.Level.Debug);
if (E.Data.Substring(0, 1) != "!")
return true;
Command C = E.isValidCMD(commands);
if (C != null)
{
C = processCommand(E, C);
if (C != null)
{
C.Execute(E);
return true;
}
else
{
Log.Write("Error processing command by " + E.Origin.getName(), Log.Level.Debug);
return true;
}
}
else
E.Origin.Tell("You entered an invalid command!");
return true;
}
if (E.Type == Event.GType.MapChange)
{
Log.Write("Map change detected..", Log.Level.Production);
return true;
//TODO here
}
if (E.Type == Event.GType.MapEnd)
{
Log.Write("Game ending...", Log.Level.Production);
return true;
}
return false;
}
//THESE MAY NEED TO BE MOVED
public void Broadcast(String Message)
{
RCON.addRCON("sayraw " + Message, 0);
}
public void Tell(String Message, Player Target)
{
RCON.addRCON("tell " + Target.getClientNum() + " " + Message + "^7", 0);
}
public void Kick(String Message, Player Target)
{
RCON.addRCON("clientkick " + Target.getClientNum() + " \"" + Message + "^7\"", 0);
}
public void Ban(String Message, Player Target, Player Origin)
{
RCON.addRCON("tempbanclient " + Target.getClientNum() + " \"" + Message + "^7\"", 0);
if (Origin != null)
{
Target.setLevel(Player.Permission.Banned);
Ban newBan = new Ban(Target.getLastO(), Target.getID(), Origin.getID());
Bans.Add(newBan);
DB.addBan(newBan);
DB.updatePlayer(Target);
}
}
public bool Unban(String GUID)
{
foreach (Ban B in Bans)
{
if (B.getID() == GUID)
{
DB.removeBan(GUID);
Bans.Remove(B);
Player P = DB.getPlayer(GUID, 0);
P.setLevel(Player.Permission.User);
DB.updatePlayer(P);
return true;
}
}
return false;
}
public void fastRestart(int delay)
{
Utilities.Wait(delay);
RCON.addRCON("fast_restart", 0);
}
public void mapRotate(int delay)
{
Utilities.Wait(delay);
RCON.addRCON("map_rotate", 0);
}
public void tempBan(String Message, Player Target)
{
RCON.addRCON("tempbanclient " + Target.getClientNum() + " \"" + Message + "\"", 0);
}
public void mapRotate()
{
RCON.addRCON("map_rotate", 0);
}
public void Map(String map)
{
RCON.addRCON("map " + map, 0);
}
//END
//THIS IS BAD BECAUSE WE DON"T WANT EVERYONE TO HAVE ACCESS :/
public String getPassword()
{
return rcon_pass;
}
private void initMaps()
{
file mapfile = new file("config\\maps.cfg");
String[] _maps = mapfile.readAll();
if (_maps.Length > 2) // readAll returns minimum one empty string
{
foreach (String m in _maps)
{
String[] m2 = m.Split(':');
if (m2.Length > 1)
{
Map map = new Map(m2[0].Trim(), m2[1].Trim());
maps.Add(map);
}
}
}
else
Log.Write("Maps configuration appears to be empty - skipping...", Log.Level.All);
}
private void initMessages()
{
file messageCFG = new file("config\\messages.cfg");
String[] lines = messageCFG.readAll();
if (lines.Length < 2) //readAll returns minimum one empty string
{
Log.Write("Messages configuration appears empty - skipping...", Log.Level.All);
return;
}
int mTime = -1;
int.TryParse(lines[0], out mTime);
if (messageTime == -1)
messageTime = 60;
else
messageTime = mTime;
foreach (String l in lines)
{
if (lines[0] != l && l.Length > 1)
messages.Add(l);
}
}
private void initRules()
{
file ruleFile = new file("config\\rules.cfg");
String[] _rules = ruleFile.readAll();
if (_rules.Length > 2) // readAll returns minimum one empty string
{
foreach (String r in _rules)
{
if (r.Length > 1)
rules.Add(r);
}
}
else
Log.Write("Rules configuration appears empty - skipping...", Log.Level.All);
}
private void initCommands()
{
// Something like *COMMAND* | NAME | HELP MSG | ALIAS | NEEDED PERMISSION | # OF REQUIRED ARGS | HAS TARGET |
commands = new List<Command>();
if(owner == null)
commands.Add(new Owner("owner", "claim ownership of the server", "owner", Player.Permission.User, 0, false));
commands.Add(new Kick("kick", "kick a player by name. syntax: !kick <player> <reason>.", "k", Player.Permission.Moderator, 2, true));
commands.Add(new Say("say", "broadcast message to all players. syntax: !say <message>.", "s", Player.Permission.Moderator, 1, false));
commands.Add(new TempBan("tempban", "temporarily ban a player for 1 hour. syntax: !tempban <player> <reason>.", "tb", Player.Permission.Moderator, 2, true));
commands.Add(new SBan("ban", "permanently ban a player from the server. syntax: !ban <player> <reason>", "b", Player.Permission.SeniorAdmin, 2, true));
commands.Add(new WhoAmI("whoami", "give information about yourself. syntax: !whoami.", "who", Player.Permission.User, 0, false));
commands.Add(new List("list", "list active clients syntax: !list.", "l", Player.Permission.Moderator, 0, false));
commands.Add(new Help("help", "list all available commands. syntax: !help.", "l", Player.Permission.User, 0, false));
commands.Add(new FastRestart("fastrestart", "fast restart current map. syntax: !fastrestart.", "fr", Player.Permission.Moderator, 0, false));
commands.Add(new MapRotate("maprotate", "cycle to the next map in rotation. syntax: !maprotate.", "mr", Player.Permission.Administrator, 0, false));
commands.Add(new SetLevel("setlevel", "set player to specified administration level. syntax: !setlevel <player> <level>.", "sl", Player.Permission.Owner, 2, true));
commands.Add(new Usage("usage", "get current application memory usage. syntax: !usage.", "u", Player.Permission.Moderator, 0, false));
commands.Add(new Uptime("uptime", "get current application running time. syntax: !uptime.", "up", Player.Permission.Moderator, 0, false));
commands.Add(new Warn("warn", "warn player for infringing rules syntax: !warn <player> <reason>.", "w", Player.Permission.Moderator, 2, true));
commands.Add(new WarnClear("warnclear", "remove all warning for a player syntax: !warnclear <player>.", "wc", Player.Permission.Administrator, 1, true));
commands.Add(new Unban("unban", "unban player by guid. syntax: !unban <guid>.", "ub", Player.Permission.Administrator, 1, false));
commands.Add(new Admins("admins", "list currently connected admins. syntax: !admins.", "a", Player.Permission.User, 0, false));
commands.Add(new Wisdom("wisdom", "get a random wisdom quote. syntax: !wisdom", "w", Player.Permission.Administrator, 0, false));
commands.Add(new MapCMD("map", "change to specified map. syntax: !map", "m", Player.Permission.Administrator, 1, false));
commands.Add(new Find("find", "find player in database. syntax: !find <player>", "f", Player.Permission.Administrator, 1, false));
commands.Add(new Rules("rules", "list server rules. syntax: !rules", "r", Player.Permission.User, 0, false));
/*
commands.Add(new commands { command = "stats", desc = "view your server stats.", requiredPer = 0 });
commands.Add(new commands { command = "speed", desc = "change player speed. syntax: !speed <number>", requiredPer = 3 });
commands.Add(new commands { command = "gravity", desc = "change game gravity. syntax: !gravity <number>", requiredPer = 3 });
commands.Add(new commands { command = "version", desc = "view current app version.", requiredPer = 0 });*/
}
//Objects
public Log Log;
public RCON RCON;
public Database DB;
public List<Ban> Bans;
public Player owner;
public List<Map> maps;
public List<String> rules;
public Queue<Event> events;
//Info
private String IP;
private int Port;
private String hostname;
private int clientnum;
private string rcon_pass;
private List<Player> players;
private List<Command> commands;
private List<String> messages;
private int messageTime;
private TimeSpan lastMessage;
private int nextMessage;
private int errors = 0;
//Log stuff
private String Basepath;
private String Mod;
private String logPath;
private file logFile;
}
}

77
Admin/Utilities.cs Normal file
View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace IW4MAdmin
{
class Utilities
{
//Get string with specified number of spaces -- really only for visual output
public static String getSpaces(int Num)
{
String SpaceString = String.Empty;
while (Num > 0)
{
SpaceString += ' ';
Num--;
}
return SpaceString;
}
//Sleep for x amount of seconds
public static void Wait(double time)
{
Thread.Sleep((int)Math.Ceiling(time*1000));
}
//Remove words from a space delimited string
public static String removeWords(String str, int num)
{
String newStr = String.Empty;
String[] tmp = str.Split(' ');
for (int i = 0; i < tmp.Length; i++)
{
if (i >= num)
newStr += tmp[i] + ' ';
}
return newStr;
}
public static Player.Permission matchPermission(String str)
{
String lookingFor = str.ToLower();
for (Player.Permission Perm = Player.Permission.User; Perm < Player.Permission.Owner; Perm++)
{
if (lookingFor.Contains(Perm.ToString().ToLower()))
return Perm;
}
return Player.Permission.Banned;
}
public static String removeNastyChars(String str)
{
return str.Replace("`", "").Replace("'", "").Replace("\\", "").Replace("\"", "").Replace("^", "").Replace("&quot;", "''");
}
public static int GetLineNumber(Exception ex)
{
var lineNumber = 0;
const string lineSearch = ":line ";
var index = ex.StackTrace.LastIndexOf(lineSearch);
if (index != -1)
{
var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
if (int.TryParse(lineNumberText, out lineNumber))
{
}
}
return lineNumber;
}
}
}

22
IW4M Admin.sln Normal file
View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IW4M ADMIN", "Admin\IW4M ADMIN.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Any CPU.Build.0 = Release|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal