Adds UserManager to sql

Changes the way Warps and Regions are stored
A few other minor tweaks
This commit is contained in:
Twitchy 2011-07-09 16:33:07 +12:00
parent 4a25cd612c
commit cb7033d89c
10 changed files with 154 additions and 430 deletions

View file

@ -301,7 +301,7 @@ namespace TShockAPI
}
string encrPass = Tools.HashPassword(args.Parameters[1]);
string[] exr = Tools.FetchHashedPasswordAndGroup(args.Parameters[0]);
string[] exr = TShock.Users.FetchHashedPasswordAndGroup(args.Parameters[0]);
if (exr[0] == encrPass)
{
args.Player.Group = Tools.GetGroup(exr[1]);
@ -329,21 +329,28 @@ namespace TShockAPI
{
if (args.Parameters[0] == "add")
{
int returnval = 0;
if (args.Parameters[1].Split(':').Length == 2)
{
TextWriter tw = new StreamWriter(FileTools.UsersPath, true);
tw.WriteLine("\n" + args.Parameters[1].Split(':')[0] + ":" + Tools.HashPassword(args.Parameters[1].Split(':')[1]) + " " + args.Parameters[2]);
tw.Close();
args.Player.SendMessage("This player can now login!", Color.Green);
if ((returnval = TShock.Users.AddUser("", args.Parameters[1].Split(':')[0], args.Parameters[1].Split(':')[1], args.Parameters[2])) == 1)
args.Player.SendMessage("This player can now login!", Color.Green);
else if(returnval == 2)
args.Player.SendMessage("Invalid Group", Color.Green);
else
args.Player.SendMessage("Could not add user", Color.Green);
return;
}
else if (args.Parameters[1].Split(':').Length == 1)
{
TextWriter tw = new StreamWriter(FileTools.UsersPath, true);
tw.WriteLine("\n" + args.Parameters[1] + " " + args.Parameters[2]);
tw.Close();
args.Player.SendMessage("IP address admin added. If they're logged in, tell them to rejoin.", Color.Green);
args.Player.SendMessage("WARNING: This is insecure! It would be better to use a user account instead.", Color.Red);
if ((returnval = TShock.Users.AddUser(args.Parameters[1], "", "", args.Parameters[2])) == 1)
{
args.Player.SendMessage("IP address admin added. If they're logged in, tell them to rejoin.", Color.Green);
args.Player.SendMessage("WARNING: This is insecure! It would be better to use a user account instead.", Color.Red);
}
else if (returnval == 2)
args.Player.SendMessage("Invalid Group", Color.Green);
else
args.Player.SendMessage("Could not add user", Color.Green);
return;
}
else

View file

@ -37,7 +37,7 @@ namespace TShockAPI.DB
using (var com = database.CreateCommand())
{
com.CommandText =
"CREATE TABLE IF NOT EXISTS \"Bans\" (\"IP\" VARCHAR(15) NOT NULL UNIQUE , \"Name\" VARCHAR(32) NOT NULL , \"Reason\" VARCHAR(255) NOT NULL );";
"CREATE TABLE IF NOT EXISTS 'Bans' ('IP' TEXT UNIQUE , 'Name' TEXT, 'Reason' TEXT);";
com.ExecuteNonQuery();
}
}

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Community.CsharpSqlite.SQLiteClient;
namespace TShockAPI.DB
{
public class GroupManager
{
private IDbConnection database;
public GroupManager(IDbConnection db)
{
database = db;
}
public bool GroupExists(string group)
{
return true;
}
}
}

View file

@ -43,7 +43,7 @@ namespace TShockAPI.DB
using (var com = database.CreateCommand())
{
com.CommandText =
"CREATE TABLE IF NOT EXISTS \"Regions\" (\"X1\" INTEGER(11) NOT NULL, \"Y1\" INTEGER(11) NOT NULL, \"X2\" INTEGER(11) NOT NULL, \"Y2\" INTEGER(11) NOT NULL, \"RegionName\" VARCHAR(32) NOT NULL, \"WorldID\" VARCHAR(255) NOT NULL, \"UserIds\" VARCHAR(255) NOT NULL, \"Protected\" INTEGER(1));";
"CREATE TABLE IF NOT EXISTS 'Regions' ('X1' INTEGER(11) NOT NULL, 'Y1' INTEGER(11) NOT NULL, 'X2' INTEGER(11) NOT NULL, 'Y2' INTEGER(11) NOT NULL, 'RegionName' VARCHAR(32) NOT NULL, 'WorldID' VARCHAR(255) NOT NULL, 'UserIds' VARCHAR(255) NOT NULL, 'Protected' INTEGER(1));";
com.ExecuteNonQuery();
}
}
@ -101,7 +101,7 @@ namespace TShockAPI.DB
{
using (var com = database.CreateCommand())
{
com.CommandText = "UPDATE Regions SET Protected='@bool' WHERE RegionName=@name WorldID=@worldid";
com.CommandText = "UPDATE Regions SET Protected=@bool WHERE RegionName=@name WorldID=@worldid";
com.AddParameter("@name", name);
if (state)
com.AddParameter("@bool", 1);

View file

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Community.CsharpSqlite.SQLiteClient;
namespace TShockAPI.DB
{
@ -35,9 +36,109 @@ namespace TShockAPI.DB
using (var com = database.CreateCommand())
{
com.CommandText =
"CREATE TABLE IF NOT EXISTS 'Users' ('ID' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , 'Username' VARCHAR(32) UNIQUE , 'Password' CHAR(32), 'Group' VARCHAR(50));";
"CREATE TABLE IF NOT EXISTS 'Users' ('ID' INTEGER PRIMARY KEY, 'Username' TEXT UNIQUE, 'Password' TEXT, 'UserGroup' TEXT, 'IP' TEXT);";
com.ExecuteNonQuery();
com.CommandText = "INSERT INTO Users (UserGroup, IP) VALUES (@group, @ip);";
com.AddParameter("@group", "superadmin");
com.AddParameter("@ip", "127.0.0.1");
com.ExecuteNonQuery();
}
}
public int AddUser(string ip = "" , string name = "", string password = "", string group = "default")
{
try
{
using (var com = database.CreateCommand())
{
com.CommandText = "INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@name, @password, @group, @ip);";
com.AddParameter("@name", name.ToLower());
com.AddParameter("@password", Tools.HashPassword(password));
if(TShock.Groups.GroupExists(group))
com.AddParameter("@group", group);
else
//Return code 2 (Group not exist)
return 2;
com.AddParameter("@ip", ip);
using (var reader = com.ExecuteReader())
{
if (reader.RecordsAffected > 0)
//Return code 1 (User added)
return 1;
else
//Return code 0 (Add failed)
return 0;
}
}
}
catch (SqliteExecutionException ex)
{
//Return code 0 (Add failed)
return 0;
}
}
/// <summary>
/// Fetches the hashed password and group for a given username
/// </summary>
/// <param name="username">string username</param>
/// <returns>string[] {password, group}</returns>
public string[] FetchHashedPasswordAndGroup(string username)
{
string[] returndata = new string[2];
try
{
using (var com = database.CreateCommand())
{
com.CommandText = "SELECT * FROM Users WHERE Username=@name";
com.AddParameter("@name", username.ToLower());
using (var reader = com.ExecuteReader())
{
if (reader.Read())
{
returndata[0] = reader.Get<string>("Password");
returndata[1] = reader.Get<string>("UserGroup");
return returndata;
}
}
}
}
catch (SqliteExecutionException ex)
{
}
return returndata;
}
/// <summary>
/// Returns a Group for a ip from the database
/// </summary>
/// <param name="ply">string ip</param>
public Group GetGroupForIP(string ip)
{
try
{
using (var com = database.CreateCommand())
{
com.CommandText = "SELECT * FROM Users WHERE IP=@ip";
com.AddParameter("@ip", ip);
using (var reader = com.ExecuteReader())
{
if (reader.Read())
{
string group = reader.Get<string>("UserGroup");
return Tools.GetGroup(group);
}
}
}
}
catch (SqliteExecutionException ex)
{
}
return Tools.GetGroup("default");
}
}
}

View file

@ -43,7 +43,7 @@ namespace TShockAPI.DB
using (var com = database.CreateCommand())
{
com.CommandText =
"CREATE TABLE IF NOT EXISTS \"Warps\" (\"X\" INTEGER(11) NOT NULL, \"Y\" INTEGER(11) NOT NULL, \"WarpName\" VARCHAR(32) NOT NULL UNIQUE, \"WorldID\" VARCHAR(255) NOT NULL );";
"CREATE TABLE IF NOT EXISTS 'Warps' ('X' INTEGER(11) NOT NULL, 'Y' INTEGER(11) NOT NULL, 'WarpName' TEXT UNIQUE, 'WorldID' TEXT);";
com.ExecuteNonQuery();
}
}

View file

@ -1,327 +0,0 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011 The TShock Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework;
using Terraria;
namespace TShockAPI
{
public class RegionManager
{
public static List<Region> Regions = new List<Region>();
public static bool AddRegion(int tx, int ty, int width, int height, string regionname, string worldname)
{
foreach (Region nametest in Regions)
{
if (regionname.ToLower() == nametest.RegionName.ToLower())
{
return false;
}
}
Regions.Add(new Region(new Rectangle(tx, ty, width, height), regionname, true, worldname));
WriteSettings();
return true;
}
public static bool AddNewUser(string regionName, string IP)
{
foreach (Region nametest in Regions)
{
if (regionName.ToLower() == nametest.RegionName.ToLower())
{
nametest.RegionAllowedIPs.Add(IP.ToLower());
return true;
}
}
return false;
}
public static bool DeleteRegion(string name)
{
foreach (Region nametest in Regions)
{
if (name.ToLower() == nametest.RegionName.ToLower() && nametest.WorldRegionName == Main.worldName)
{
Regions.Remove(nametest);
WriteSettings();
return true;
}
}
return false;
}
public static bool SetRegionState(string name, bool state)
{
foreach (Region nametest in Regions)
{
if (name.ToLower() == nametest.RegionName.ToLower())
{
nametest.DisableBuild = state;
WriteSettings();
return true;
}
}
return false;
}
public static bool InProtectedArea(int X, int Y, string IP)
{
foreach(Region region in Regions)
{
if (X >= region.RegionArea.Left && X <= region.RegionArea.Right &&
Y >= region.RegionArea.Top && Y <= region.RegionArea.Bottom &&
region.DisableBuild && Main.worldName == region.WorldRegionName &&
(!AllowedUser(region.RegionName, IP.ToLower()) || region.RegionAllowedIPs.Count == 0))
{
return true;
}
}
return false;
}
public static int GetRegionIndex(string regionName)
{
for(int i = 0; i< Regions.Count;i++)
{
if(Regions[i].RegionName == regionName)
return i;
}
return -1;
}
public static bool AllowedUser(string regionName, string playerIP)
{
int ID = -1;
if ((ID = GetRegionIndex(regionName)) != -1)
{
for (int i = 0; i < Regions[ID].RegionAllowedIPs.Count; i++)
{
if (Regions[ID].RegionAllowedIPs[i].ToLower() == playerIP.ToLower())
{
return true;
}
}
}
return false;
}
public static void WriteSettings()
{
try
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.NewLineChars = Environment.NewLine;
using (XmlWriter settingsw = XmlWriter.Create(FileTools.RegionsPath, xmlWriterSettings))
{
settingsw.WriteStartDocument();
settingsw.WriteStartElement("Regions");
foreach (Region region in Regions)
{
settingsw.WriteStartElement("ProtectedRegion");
settingsw.WriteElementString("RegionName", region.RegionName);
settingsw.WriteElementString("Point1X", region.RegionArea.X.ToString());
settingsw.WriteElementString("Point1Y", region.RegionArea.Y.ToString());
settingsw.WriteElementString("Point2X", region.RegionArea.Width.ToString());
settingsw.WriteElementString("Point2Y", region.RegionArea.Height.ToString());
settingsw.WriteElementString("Protected", region.DisableBuild.ToString());
settingsw.WriteElementString("WorldName", region.WorldRegionName);
settingsw.WriteElementString("AllowedUserCount", region.RegionAllowedIPs.Count.ToString());
for (int i = 0; i < region.RegionAllowedIPs.Count; i++)
{
settingsw.WriteElementString("IP", region.RegionAllowedIPs[i]);
}
settingsw.WriteEndElement();
}
settingsw.WriteEndElement();
settingsw.WriteEndDocument();
}
Log.Info("Wrote Regions");
}
catch
{
Log.Warn("Could not write Regions");
}
}
public static void ReadAllSettings()
{
try
{
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
xmlReaderSettings.IgnoreWhitespace = true;
using (XmlReader settingr = XmlReader.Create(FileTools.RegionsPath, xmlReaderSettings))
{
while (settingr.Read())
{
if (settingr.IsStartElement())
{
switch (settingr.Name)
{
case "Regions":
{
break;
}
case "ProtectedRegion":
{
if (settingr.Read())
{
string name = null;
int x = 0;
int y = 0;
int width = 0;
int height = 0;
bool state = true;
string worldname = null;
int playercount = 0;
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
name = settingr.Value;
else
Log.Warn("Region name is empty");
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
Int32.TryParse(settingr.Value, out x);
else
Log.Warn("x for region " + name + " is empty");
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
Int32.TryParse(settingr.Value, out y);
else
Log.Warn("y for region " + name + " is empty");
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
Int32.TryParse(settingr.Value, out width);
else
Log.Warn("Width for region " + name + " is empty");
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
Int32.TryParse(settingr.Value, out height);
else
Log.Warn("Height for region " + name + " is empty");
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
bool.TryParse(settingr.Value, out state);
else
Log.Warn("State for region " + name + " is empty");
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
worldname = settingr.Value;
else
Log.Warn("Worldname for region " + name + " is empty");
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
Int32.TryParse(settingr.Value, out playercount);
else
Log.Warn("Playercount for region " + name + " is empty");
AddRegion(x, y, width, height, name, worldname);
if (playercount > 0)
{
for (int i = 0; i < playercount; i++)
{
settingr.Read();
settingr.Read();
settingr.Read();
if (settingr.Value != "" || settingr.Value != null)
{
int ID = RegionManager.GetRegionIndex(name);
Regions[ID].RegionAllowedIPs.Add(settingr.Value);
}
else
Log.Warn("PlayerIP " + i + " for region " + name + " is empty");
}
}
}
break;
}
}
}
}
}
Log.Info("Read Regions");
}
catch
{
Log.Warn("Could not read Regions");
WriteSettings();
}
}
}
public class Region
{
public Rectangle RegionArea { get; set; }
public string RegionName { get; set; }
public bool DisableBuild { get; set; }
public string WorldRegionName { get; set; }
public List<string> RegionAllowedIPs = new List<string>();
public Region(Rectangle region, string name, bool disablebuild, string worldname)
{
RegionArea = region;
RegionName = name;
DisableBuild = disablebuild;
WorldRegionName = worldname;
}
public Region()
{
RegionArea = Rectangle.Empty;
RegionName = string.Empty;
DisableBuild = true;
WorldRegionName = string.Empty;
}
}
}

View file

@ -47,6 +47,8 @@ namespace TShockAPI
public static WarpManager Warps;
public static RegionManager Regions;
public static BackupManager Backups;
public static GroupManager Groups;
public static UserManager Users;
public static ConfigFile Config { get; set; }
@ -114,6 +116,8 @@ namespace TShockAPI
Bans = new BanManager(DB);
Warps = new WarpManager(DB);
Regions = new RegionManager(DB);
Groups = new GroupManager(DB);
Users = new UserManager(DB);
Log.ConsoleInfo(string.Format("TShock Version {0} ({1}) now running.", Version, VersionCodename));
@ -270,7 +274,7 @@ namespace TShockAPI
private void OnJoin(int ply, HandledEventArgs handler)
{
var player = new TSPlayer(ply);
player.Group = Tools.GetGroupForIP(player.IP);
player.Group = TShock.Users.GetGroupForIP(player.IP);
if (Tools.ActivePlayers() + 1 > TShock.Config.MaxSlots && !player.Group.HasPermission("reservedslot"))
{
@ -294,8 +298,6 @@ namespace TShockAPI
}
Players[ply] = player;
}
private void OnLeave(int ply)

View file

@ -78,6 +78,7 @@
<Compile Include="BackupManager.cs" />
<Compile Include="DB\BanManager.cs" />
<Compile Include="DB\DbExt.cs" />
<Compile Include="DB\GroupManager.cs" />
<Compile Include="DB\UserManager.cs" />
<Compile Include="IPackable.cs" />
<Compile Include="ItemManager.cs" />
@ -88,7 +89,7 @@
<Compile Include="Group.cs" />
<Compile Include="Log.cs" />
<Compile Include="Net\NetTile.cs" />
<Compile Include="RegionManager.cs" />
<Compile Include="DB\RegionManager.cs" />
<Compile Include="RememberPosManager.cs" />
<Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen>

View file

@ -533,90 +533,6 @@ namespace TShockAPI
return new Group("null");
}
/// <summary>
/// Returns a Group for a ip from users.txt
/// </summary>
/// <param name="ply">string ip</param>
public static Group GetGroupForIP(string ip)
{
ip = GetRealIP(ip);
StreamReader sr = new StreamReader(FileTools.UsersPath);
string data = sr.ReadToEnd();
data = data.Replace("\r", "");
string[] lines = data.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
string[] args = lines[i].Split(' ');
if (args.Length < 2)
{
continue;
}
if (args[0].Contains(":"))
{
continue;
}
if (lines[i].StartsWith("#"))
{
continue;
}
try
{
var hi = GetIPv4Address(args[0]);
if (GetIPv4Address(args[0]).Equals(ip))
return GetGroup(args[1]);
}
catch (Exception ex)
{ Log.Error(ex.ToString()); }
}
sr.Close();
return GetGroup("default");
}
/// <summary>
/// Fetches the hashed password and group for a given username
/// </summary>
/// <param name="username">string username</param>
/// <returns>string[] {password, group}</returns>
public static string[] FetchHashedPasswordAndGroup(string username)
{
StreamReader sr = new StreamReader(FileTools.UsersPath);
string data = sr.ReadToEnd();
data = data.Replace("\r", "");
string[] lines = data.Split('\n');
string[] result = {"null", "null"};
for (int i = 0; i < lines.Length; i++)
{
string[] args = lines[i].Split(' ');
if (args.Length < 2)
{
continue;
}
if (lines[i].StartsWith("#"))
{
continue;
}
if (!lines[i].Contains(":"))
{
continue;
}
try
{
if (args[0].Split(':')[0].ToLower() == username.ToLower())
{
result = new string[] {args[0].Split(':')[1], args[1]};
return result;
}
}
catch (Exception ex)
{ Log.Error(ex.ToString()); }
}
sr.Close();
return result;
}
/// <summary>
/// Returns an IPv4 address from a DNS query
/// </summary>