Merge branch 'general-devel' of github.com:TShock/TShock
Conflicts: DBEditor/Main.Designer.cs DBEditor/Main.cs
This commit is contained in:
commit
4cf35a3093
50 changed files with 2567 additions and 1506 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -51,4 +51,5 @@ Thumbs.db
|
|||
|
||||
#Template Bat file#
|
||||
###################
|
||||
myass.bat
|
||||
myass.bat
|
||||
/TestResults
|
||||
|
|
@ -5,21 +5,23 @@ using System.Text;
|
|||
|
||||
namespace TShockDBEditor
|
||||
{
|
||||
public class Commandlist
|
||||
public class TShockCommandsList
|
||||
{
|
||||
public static List<string> CommandList = new List<string>();
|
||||
|
||||
public static void AddCommands()
|
||||
public static void AddRemainingTShockCommands()
|
||||
{
|
||||
List<string> CommandList = new List<string>();
|
||||
|
||||
CommandList.Add("reservedslot");
|
||||
CommandList.Add("canwater");
|
||||
CommandList.Add("canlava");
|
||||
CommandList.Add("canbuild");
|
||||
CommandList.Add("adminchat");
|
||||
CommandList.Add("warp");
|
||||
CommandList.Add("kick");
|
||||
CommandList.Add("ban");
|
||||
CommandList.Add("unban");
|
||||
CommandList.Add("whitelist");
|
||||
CommandList.Add("maintenace");
|
||||
CommandList.Add("maintenance");
|
||||
CommandList.Add("causeevents");
|
||||
CommandList.Add("spawnboss");
|
||||
CommandList.Add("spawnmob");
|
||||
|
|
@ -42,6 +44,12 @@ namespace TShockDBEditor
|
|||
CommandList.Add("ignorecheatdetection");
|
||||
CommandList.Add("ignoregriefdetection");
|
||||
CommandList.Add("usebanneditem");
|
||||
|
||||
foreach (string command in CommandList)
|
||||
{
|
||||
if (!TShockDBEditor.CommandList.Contains(command))
|
||||
TShockDBEditor.CommandList.Add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
47
DBEditor/Main.Designer.cs
generated
47
DBEditor/Main.Designer.cs
generated
|
|
@ -82,6 +82,8 @@
|
|||
this.label14 = new System.Windows.Forms.Label();
|
||||
this.lst_userlist = new System.Windows.Forms.ListBox();
|
||||
this.tabPage6 = new System.Windows.Forms.TabPage();
|
||||
this.groupBox7 = new System.Windows.Forms.GroupBox();
|
||||
this.lst_bans = new System.Windows.Forms.ListBox();
|
||||
this.groupBox6 = new System.Windows.Forms.GroupBox();
|
||||
this.lbl_newbanstatus = new System.Windows.Forms.Label();
|
||||
this.label16 = new System.Windows.Forms.Label();
|
||||
|
|
@ -99,7 +101,6 @@
|
|||
this.label19 = new System.Windows.Forms.Label();
|
||||
this.txt_banreason = new System.Windows.Forms.TextBox();
|
||||
this.label18 = new System.Windows.Forms.Label();
|
||||
this.lst_bans = new System.Windows.Forms.ListBox();
|
||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||
this.tabPage3 = new System.Windows.Forms.TabPage();
|
||||
this.btn_OpenLocalDB = new System.Windows.Forms.Button();
|
||||
|
|
@ -115,7 +116,6 @@
|
|||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.groupBox7 = new System.Windows.Forms.GroupBox();
|
||||
this.tabControl.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.tabPage2.SuspendLayout();
|
||||
|
|
@ -125,12 +125,12 @@
|
|||
this.groupBox4.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.tabPage6.SuspendLayout();
|
||||
this.groupBox7.SuspendLayout();
|
||||
this.groupBox6.SuspendLayout();
|
||||
this.groupBox5.SuspendLayout();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage3.SuspendLayout();
|
||||
this.tabPage4.SuspendLayout();
|
||||
this.groupBox7.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// itemListBanned
|
||||
|
|
@ -675,6 +675,25 @@
|
|||
this.tabPage6.Text = "Ban Manager";
|
||||
this.tabPage6.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox7
|
||||
//
|
||||
this.groupBox7.Controls.Add(this.lst_bans);
|
||||
this.groupBox7.Location = new System.Drawing.Point(6, 23);
|
||||
this.groupBox7.Name = "groupBox7";
|
||||
this.groupBox7.Size = new System.Drawing.Size(284, 352);
|
||||
this.groupBox7.TabIndex = 13;
|
||||
this.groupBox7.TabStop = false;
|
||||
this.groupBox7.Text = "Ban List";
|
||||
//
|
||||
// lst_bans
|
||||
//
|
||||
this.lst_bans.FormattingEnabled = true;
|
||||
this.lst_bans.Location = new System.Drawing.Point(6, 19);
|
||||
this.lst_bans.Name = "lst_bans";
|
||||
this.lst_bans.Size = new System.Drawing.Size(272, 329);
|
||||
this.lst_bans.TabIndex = 0;
|
||||
this.lst_bans.SelectedIndexChanged += new System.EventHandler(this.lst_bans_SelectedIndexChanged);
|
||||
//
|
||||
// groupBox6
|
||||
//
|
||||
this.groupBox6.Controls.Add(this.lbl_newbanstatus);
|
||||
|
|
@ -839,15 +858,6 @@
|
|||
this.label18.TabIndex = 4;
|
||||
this.label18.Text = "Name:";
|
||||
//
|
||||
// lst_bans
|
||||
//
|
||||
this.lst_bans.FormattingEnabled = true;
|
||||
this.lst_bans.Location = new System.Drawing.Point(6, 19);
|
||||
this.lst_bans.Name = "lst_bans";
|
||||
this.lst_bans.Size = new System.Drawing.Size(272, 329);
|
||||
this.lst_bans.TabIndex = 0;
|
||||
this.lst_bans.SelectedIndexChanged += new System.EventHandler(this.lst_bans_SelectedIndexChanged);
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
this.tabControl1.Controls.Add(this.tabPage3);
|
||||
|
|
@ -992,16 +1002,6 @@
|
|||
this.label5.TabIndex = 0;
|
||||
this.label5.Text = "Hostname:";
|
||||
//
|
||||
// groupBox7
|
||||
//
|
||||
this.groupBox7.Controls.Add(this.lst_bans);
|
||||
this.groupBox7.Location = new System.Drawing.Point(6, 23);
|
||||
this.groupBox7.Name = "groupBox7";
|
||||
this.groupBox7.Size = new System.Drawing.Size(284, 352);
|
||||
this.groupBox7.TabIndex = 13;
|
||||
this.groupBox7.TabStop = false;
|
||||
this.groupBox7.Text = "Ban List";
|
||||
//
|
||||
// TShockDBEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
|
@ -1011,6 +1011,7 @@
|
|||
this.Controls.Add(this.tabControl);
|
||||
this.Name = "TShockDBEditor";
|
||||
this.Text = "TShockDBEditor";
|
||||
this.Load += new System.EventHandler(this.TShockDBEditor_Load);
|
||||
this.tabControl.ResumeLayout(false);
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
|
|
@ -1026,6 +1027,7 @@
|
|||
this.groupBox3.ResumeLayout(false);
|
||||
this.groupBox3.PerformLayout();
|
||||
this.tabPage6.ResumeLayout(false);
|
||||
this.groupBox7.ResumeLayout(false);
|
||||
this.groupBox6.ResumeLayout(false);
|
||||
this.groupBox6.PerformLayout();
|
||||
this.groupBox5.ResumeLayout(false);
|
||||
|
|
@ -1034,7 +1036,6 @@
|
|||
this.tabPage3.ResumeLayout(false);
|
||||
this.tabPage4.ResumeLayout(false);
|
||||
this.tabPage4.PerformLayout();
|
||||
this.groupBox7.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ namespace TShockDBEditor
|
|||
{
|
||||
public OpenFileDialog dialog = new OpenFileDialog();
|
||||
public List<Group> groups = new List<Group>();
|
||||
public static List<string> CommandList = new List<string>();
|
||||
public IDbConnection DB;
|
||||
public string dbtype = "";
|
||||
|
||||
|
|
@ -25,7 +26,6 @@ namespace TShockDBEditor
|
|||
{
|
||||
InitializeComponent();
|
||||
Itemlist.AddItems();
|
||||
Commandlist.AddCommands();
|
||||
dialog.FileOk += new CancelEventHandler(dialog_FileOk);
|
||||
dialog.Filter = "SQLite Database (*.sqlite)|*.sqlite";
|
||||
}
|
||||
|
|
@ -50,6 +50,7 @@ namespace TShockDBEditor
|
|||
itemListBanned.Items.Add(reader.Get<string>("ItemName"));
|
||||
}
|
||||
}
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
|
|
@ -68,6 +69,21 @@ namespace TShockDBEditor
|
|||
lst_newusergrplist.Items.Add(reader.Get<string>("GroupName"));
|
||||
}
|
||||
}
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
foreach (string command in reader.Get<string>("Commands").Split(','))
|
||||
{
|
||||
if (!lst_groupList.Items.Contains(command))
|
||||
if (!CommandList.Contains(command))
|
||||
CommandList.Add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TShockCommandsList.AddRemainingTShockCommands();
|
||||
}
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
|
|
@ -203,7 +219,10 @@ namespace TShockDBEditor
|
|||
|
||||
private void lst_groupList_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateGroupIndex(lst_groupList.SelectedIndex);
|
||||
if ((string)lst_groupList.SelectedItem != "superadmin")
|
||||
UpdateGroupIndex(lst_groupList.SelectedIndex);
|
||||
else
|
||||
lst_groupList.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
private void UpdateGroupIndex(int index)
|
||||
|
|
@ -238,10 +257,10 @@ namespace TShockDBEditor
|
|||
if (lbl_grpchild.Text == "")
|
||||
lbl_grpchild.Text = "none";
|
||||
|
||||
for (int i = 0; i < Commandlist.CommandList.Count; i++)
|
||||
for (int i = 0; i < CommandList.Count; i++)
|
||||
{
|
||||
if (!lst_AvailableCmds.Items.Contains(Commandlist.CommandList[i]))
|
||||
lst_bannedCmds.Items.Add(Commandlist.CommandList[i]);
|
||||
if (!lst_AvailableCmds.Items.Contains(CommandList[i]))
|
||||
lst_bannedCmds.Items.Add(CommandList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -535,6 +554,8 @@ namespace TShockDBEditor
|
|||
|
||||
#endregion
|
||||
|
||||
#region UserTab
|
||||
|
||||
private void lst_userlist_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
txt_username.Text = "None Selected";
|
||||
|
|
@ -728,5 +749,12 @@ namespace TShockDBEditor
|
|||
return bytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void TShockDBEditor_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,6 @@
|
|||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
|
|
@ -75,8 +74,8 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="CommandList.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="DbExt.cs" />
|
||||
<Compile Include="Main.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
####Do not download the latest master!
|
||||
|
||||
TShock is a server modification based upon High6's mod API that allows for basic server administration commands.
|
||||
|
||||
__Constant builds__: http://ci.tshock.co/
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Terraria;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011 The TShock Team
|
||||
|
||||
|
|
@ -17,12 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
|
|
@ -138,13 +137,16 @@ namespace TShockAPI
|
|||
ChatCommands.Add(new Command("warp", UseWarp, "warp"));
|
||||
ChatCommands.Add(new Command("managewarp", SetWarp, "setwarp"));
|
||||
ChatCommands.Add(new Command("managewarp", DeleteWarp, "delwarp"));
|
||||
ChatCommands.Add(new Command("managegroup", AddGroup, "addGroup"));
|
||||
ChatCommands.Add(new Command("managegroup", DeleteGroup, "delGroup"));
|
||||
ChatCommands.Add(new Command("managegroup", ModifyGroup, "modGroup"));
|
||||
ChatCommands.Add(new Command("managewarp", HideWarp, "hidewarp"));
|
||||
ChatCommands.Add(new Command("managegroup", AddGroup, "addgroup"));
|
||||
ChatCommands.Add(new Command("managegroup", DeleteGroup, "delgroup"));
|
||||
ChatCommands.Add(new Command("managegroup", ModifyGroup, "modgroup"));
|
||||
ChatCommands.Add(new Command("manageitem", AddItem, "additem"));
|
||||
ChatCommands.Add(new Command("manageitem", DeleteItem, "delitem"));
|
||||
ChatCommands.Add(new Command("cfg", SetSpawn, "setspawn"));
|
||||
ChatCommands.Add(new Command("cfg", Reload, "reload"));
|
||||
ChatCommands.Add(new Command("cfg", DebugConfiguration, "debug-config"));
|
||||
ChatCommands.Add(new Command("cfg", Password, "password"));
|
||||
ChatCommands.Add(new Command("cfg", ShowConfiguration, "showconfig"));
|
||||
ChatCommands.Add(new Command("cfg", ServerPassword, "serverpassword"));
|
||||
ChatCommands.Add(new Command("cfg", Save, "save"));
|
||||
ChatCommands.Add(new Command("cfg", MaxSpawns, "maxspawns"));
|
||||
ChatCommands.Add(new Command("cfg", SpawnRate, "spawnrate"));
|
||||
|
|
@ -370,7 +372,7 @@ namespace TShockAPI
|
|||
catch (UserManagerException ex)
|
||||
{
|
||||
args.Player.SendMessage("Sorry, an error occured: " + ex.Message, Color.Green);
|
||||
Log.ConsoleError("RegisterUser returned an error: " + ex.ToString());
|
||||
Log.ConsoleError("RegisterUser returned an error: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -383,7 +385,7 @@ namespace TShockAPI
|
|||
var user = new User();
|
||||
user.Name = args.Parameters[0].ToLower();
|
||||
user.Password = args.Parameters[1];
|
||||
user.Group = "default"; // FIXME -- we should get this from the DB.
|
||||
user.Group = TShock.Config.DefaultRegistrationGroupName; // FIXME -- we should get this from the DB.
|
||||
|
||||
if (TShock.Users.GetUserByName(user.Name) == null) // Cheap way of checking for existance of a user
|
||||
{
|
||||
|
|
@ -406,7 +408,7 @@ namespace TShockAPI
|
|||
catch (UserManagerException ex)
|
||||
{
|
||||
args.Player.SendMessage("Sorry, an error occured: " + ex.Message, Color.Green);
|
||||
Log.ConsoleError("RegisterUser returned an error: " + ex.ToString());
|
||||
Log.ConsoleError("RegisterUser returned an error: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -414,15 +416,18 @@ namespace TShockAPI
|
|||
|
||||
private static void ManageUsers(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count < 2)
|
||||
{
|
||||
args.Player.SendMessage("Syntax: /user <add/del> <ip/user:pass> [group]");
|
||||
args.Player.SendMessage("Note: Passwords are stored with SHA512 hashing. To reset a user's password, remove and re-add them.");
|
||||
return;
|
||||
}
|
||||
// This guy needs to go away for the help later on to take effect.
|
||||
|
||||
//if (args.Parameters.Count < 2)
|
||||
//{
|
||||
// args.Player.SendMessage("Syntax: /user <add/del> <ip/user:pass> [group]");
|
||||
// args.Player.SendMessage("Note: Passwords are stored with SHA512 hashing. To reset a user's password, remove and re-add them.");
|
||||
// return;
|
||||
//}
|
||||
|
||||
string subcmd = args.Parameters[0];
|
||||
|
||||
// Add requires a username:password pair/ip address and a group specified.
|
||||
if (subcmd == "add")
|
||||
{
|
||||
var namepass = args.Parameters[1].Split(':');
|
||||
|
|
@ -469,6 +474,7 @@ namespace TShockAPI
|
|||
Log.ConsoleError(ex.ToString());
|
||||
}
|
||||
}
|
||||
// User deletion requires a username
|
||||
else if (subcmd == "del" && args.Parameters.Count == 2)
|
||||
{
|
||||
var user = new User();
|
||||
|
|
@ -489,13 +495,86 @@ namespace TShockAPI
|
|||
Log.ConsoleError(ex.ToString());
|
||||
}
|
||||
}
|
||||
// Password changing requires a username, and a new password to set
|
||||
else if (subcmd == "password")
|
||||
{
|
||||
var user = new User();
|
||||
user.Name = args.Parameters[1];
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (args.Parameters.Count == 3)
|
||||
{
|
||||
args.Player.SendMessage("Changed the password of " + user.Name + "!", Color.Green);
|
||||
TShock.Users.SetUserPassword(user, args.Parameters[2]);
|
||||
Log.ConsoleInfo(args.Player.Name + " changed the password of Account " + user.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Invalid user password syntax. Try /user help.", Color.Red);
|
||||
}
|
||||
}
|
||||
catch (UserManagerException ex)
|
||||
{
|
||||
args.Player.SendMessage(ex.Message, Color.Green);
|
||||
Log.ConsoleError(ex.ToString());
|
||||
}
|
||||
}
|
||||
// Group changing requires a username or IP address, and a new group to set
|
||||
else if (subcmd == "group")
|
||||
{
|
||||
var user = new User();
|
||||
if (args.Parameters[1].Contains("."))
|
||||
user.Address = args.Parameters[1];
|
||||
else
|
||||
user.Name = args.Parameters[1];
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (args.Parameters.Count == 3)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(user.Address))
|
||||
{
|
||||
args.Player.SendMessage("IP Address " + user.Address + " has been changed to group " + args.Parameters[2] + "!", Color.Green);
|
||||
TShock.Users.SetUserGroup(user, args.Parameters[2]);
|
||||
Log.ConsoleInfo(args.Player.Name + " changed IP Address " + user.Address + " to group " + args.Parameters[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Account " + user.Name + " has been changed to group " + args.Parameters[2] + "!", Color.Green);
|
||||
TShock.Users.SetUserGroup(user, args.Parameters[2]);
|
||||
Log.ConsoleInfo(args.Player.Name + " changed Account " + user.Name + " to group " + args.Parameters[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Invalid user group syntax. Try /user help.", Color.Red);
|
||||
}
|
||||
}
|
||||
catch (UserManagerException ex)
|
||||
{
|
||||
args.Player.SendMessage(ex.Message, Color.Green);
|
||||
Log.ConsoleError(ex.ToString());
|
||||
}
|
||||
}
|
||||
else if (subcmd == "help")
|
||||
{
|
||||
args.Player.SendMessage("Help for user subcommands:");
|
||||
args.Player.SendMessage("/user add username:password group -- Adds a specified user");
|
||||
args.Player.SendMessage("/user del username -- Removes a specified user");
|
||||
args.Player.SendMessage("/user password username newpassword -- Changes a user's password");
|
||||
args.Player.SendMessage("/user group username newgroup -- Changes a user's group");
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Invalid syntax. Try /user help.", Color.Red);
|
||||
args.Player.SendMessage("Invalid user syntax. Try /user help.", Color.Red);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Player Management Commands
|
||||
|
||||
private static void GrabUserIP(CommandArgs args)
|
||||
|
|
@ -626,7 +705,18 @@ namespace TShockAPI
|
|||
if (TShock.Bans.RemoveBan(ban.IP))
|
||||
args.Player.SendMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
else
|
||||
args.Player.SendMessage(string.Format("Failed to Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
args.Player.SendMessage(string.Format("Failed to unban {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
}
|
||||
else if (!TShock.Config.EnableBanOnUsernames)
|
||||
{
|
||||
ban = TShock.Bans.GetBanByIp(plStr);
|
||||
|
||||
if (ban == null)
|
||||
args.Player.SendMessage(string.Format("Failed to unban {0}, not found.", args.Parameters[0]), Color.Red);
|
||||
else if (TShock.Bans.RemoveBan(ban.IP))
|
||||
args.Player.SendMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
else
|
||||
args.Player.SendMessage(string.Format("Failed to unban {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -695,7 +785,7 @@ namespace TShockAPI
|
|||
if (TShock.Bans.RemoveBan(ban.IP))
|
||||
args.Player.SendMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
else
|
||||
args.Player.SendMessage(string.Format("Failed to Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
args.Player.SendMessage(string.Format("Failed to unban {0} ({1})!", ban.Name, ban.IP), Color.Red);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -859,7 +949,7 @@ namespace TShockAPI
|
|||
return;
|
||||
}
|
||||
NPC eater = Tools.GetNPCById(13);
|
||||
TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
Tools.Broadcast(string.Format("{0} has spawned eater of worlds {1} times!", args.Player.Name, amount));
|
||||
}
|
||||
|
||||
|
|
@ -878,7 +968,7 @@ namespace TShockAPI
|
|||
}
|
||||
NPC eye = Tools.GetNPCById(4);
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
Tools.Broadcast(string.Format("{0} has spawned eye {1} times!", args.Player.Name, amount));
|
||||
}
|
||||
|
||||
|
|
@ -896,7 +986,7 @@ namespace TShockAPI
|
|||
return;
|
||||
}
|
||||
NPC king = Tools.GetNPCById(50);
|
||||
TSPlayer.Server.SpawnNPC(king.type, king.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(king.type, king.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
Tools.Broadcast(string.Format("{0} has spawned king slime {1} times!", args.Player.Name, amount));
|
||||
}
|
||||
|
||||
|
|
@ -915,7 +1005,7 @@ namespace TShockAPI
|
|||
}
|
||||
NPC skeletron = Tools.GetNPCById(35);
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
Tools.Broadcast(string.Format("{0} has spawned skeletron {1} times!", args.Player.Name, amount));
|
||||
}
|
||||
|
||||
|
|
@ -937,10 +1027,10 @@ namespace TShockAPI
|
|||
NPC king = Tools.GetNPCById(50);
|
||||
NPC skeletron = Tools.GetNPCById(35);
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(king.type, king.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(king.type, king.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, args.Player.TileX, args.Player.TileY);
|
||||
Tools.Broadcast(string.Format("{0} has spawned all bosses {1} times!", args.Player.Name, amount));
|
||||
}
|
||||
|
||||
|
|
@ -977,7 +1067,7 @@ namespace TShockAPI
|
|||
var npc = npcs[0];
|
||||
if (npc.type >= 1 && npc.type < Main.maxNPCTypes)
|
||||
{
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.name, amount, (int)args.Player.TileX, (int)args.Player.TileY, 50, 20);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.name, amount, args.Player.TileX, args.Player.TileY, 50, 20);
|
||||
Tools.Broadcast(string.Format("{0} was spawned {1} time(s).", npc.name, amount));
|
||||
}
|
||||
else
|
||||
|
|
@ -1128,6 +1218,31 @@ namespace TShockAPI
|
|||
args.Player.SendMessage("Invalid syntax! Proper syntax: /delwarp [name]", Color.Red);
|
||||
}
|
||||
|
||||
private static void HideWarp(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count > 1)
|
||||
{
|
||||
string warpName = String.Join(" ", args.Parameters);
|
||||
bool state = false;
|
||||
if (Boolean.TryParse(args.Parameters[1], out state))
|
||||
{
|
||||
if (TShock.Warps.HideWarp(args.Parameters[0], state))
|
||||
{
|
||||
if (state)
|
||||
args.Player.SendMessage("Made warp " + warpName + " private", Color.Yellow);
|
||||
else
|
||||
args.Player.SendMessage("Made warp " + warpName + " public", Color.Yellow);
|
||||
}
|
||||
else
|
||||
args.Player.SendMessage("Could not find specified warp", Color.Red);
|
||||
}
|
||||
else
|
||||
args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [name] <true/false>", Color.Red);
|
||||
}
|
||||
else
|
||||
args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [name] <true/false>", Color.Red);
|
||||
}
|
||||
|
||||
private static void UseWarp(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count < 1)
|
||||
|
|
@ -1156,7 +1271,7 @@ namespace TShockAPI
|
|||
page--; //Substract 1 as pages are parsed starting at 1 and not 0
|
||||
}
|
||||
|
||||
var warps = TShock.Warps.ListAllWarps(Main.worldID.ToString());
|
||||
var warps = TShock.Warps.ListAllPublicWarps(Main.worldID.ToString());
|
||||
|
||||
//Check if they are trying to access a page that doesn't exist.
|
||||
int pagecount = warps.Count / pagelimit;
|
||||
|
|
@ -1207,7 +1322,6 @@ namespace TShockAPI
|
|||
|
||||
#endregion Teleport Commands
|
||||
|
||||
|
||||
#region Group Management
|
||||
|
||||
private static void AddGroup(CommandArgs args)
|
||||
|
|
@ -1218,7 +1332,7 @@ namespace TShockAPI
|
|||
args.Parameters.RemoveAt(0);
|
||||
String permissions = String.Join(",", args.Parameters );
|
||||
|
||||
String response = TShock.Groups.addGroup(groupname, permissions);
|
||||
String response = TShock.Groups.AddGroup(groupname, permissions);
|
||||
if( response.Length > 0 )
|
||||
args.Player.SendMessage(response, Color.Green);
|
||||
}
|
||||
|
|
@ -1234,7 +1348,7 @@ namespace TShockAPI
|
|||
{
|
||||
String groupname = args.Parameters[0];
|
||||
|
||||
String response = TShock.Groups.delGroup(groupname);
|
||||
String response = TShock.Groups.DeleteGroup(groupname);
|
||||
if (response.Length > 0)
|
||||
args.Player.SendMessage(response, Color.Green);
|
||||
}
|
||||
|
|
@ -1256,14 +1370,14 @@ namespace TShockAPI
|
|||
|
||||
if (com.Equals("add"))
|
||||
{
|
||||
String response = TShock.Groups.addPermission(groupname, args.Parameters);
|
||||
String response = TShock.Groups.AddPermissions(groupname, args.Parameters);
|
||||
if (response.Length > 0)
|
||||
args.Player.SendMessage(response, Color.Green);
|
||||
return;
|
||||
}
|
||||
else if (com.Equals("del") || com.Equals("delete"))
|
||||
{
|
||||
String response = TShock.Groups.delPermission(groupname, args.Parameters);
|
||||
String response = TShock.Groups.DeletePermissions(groupname, args.Parameters);
|
||||
if (response.Length > 0)
|
||||
args.Player.SendMessage(response, Color.Green);
|
||||
return;
|
||||
|
|
@ -1273,6 +1387,77 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
#endregion Group Management
|
||||
|
||||
#region Item Management
|
||||
|
||||
private static void AddItem(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count > 0)
|
||||
{
|
||||
var items = Tools.GetItemByIdOrName(args.Parameters[0]);
|
||||
if (items.Count == 0)
|
||||
{
|
||||
args.Player.SendMessage("Invalid item type!", Color.Red);
|
||||
}
|
||||
else if (items.Count > 1)
|
||||
{
|
||||
args.Player.SendMessage(string.Format("More than one ({0}) item matched!", items.Count), Color.Red);
|
||||
}
|
||||
else
|
||||
{
|
||||
var item = items[0];
|
||||
if (item.type >= 1)
|
||||
{
|
||||
TShock.Itembans.AddNewBan(args.Parameters[0]);
|
||||
args.Player.SendMessage(Tools.GetItemByIdOrName(args.Parameters[0])[0].name + " has been banned.", Color.Green);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Invalid item type!", Color.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Invalid use: /addItem \"item name\" or /addItem ##", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteItem(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count > 0)
|
||||
{
|
||||
var items = Tools.GetItemByIdOrName(args.Parameters[0]);
|
||||
if (items.Count == 0)
|
||||
{
|
||||
args.Player.SendMessage("Invalid item type!", Color.Red);
|
||||
}
|
||||
else if (items.Count > 1)
|
||||
{
|
||||
args.Player.SendMessage(string.Format("More than one ({0}) item matched!", items.Count), Color.Red);
|
||||
}
|
||||
else
|
||||
{
|
||||
var item = items[0];
|
||||
if (item.type >= 1)
|
||||
{
|
||||
TShock.Itembans.RemoveBan(args.Parameters[0]);
|
||||
args.Player.SendMessage(Tools.GetItemByIdOrName(args.Parameters[0])[0].name + " has been unbanned.", Color.Green);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Invalid item type!", Color.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.SendMessage("Invalid use: /delItem \"item name\" or /delItem ##", Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Item Management
|
||||
|
||||
#region Server Config Commands
|
||||
|
||||
private static void SetSpawn(CommandArgs args)
|
||||
|
|
@ -1285,7 +1470,7 @@ namespace TShockAPI
|
|||
SaveWorld.Start();
|
||||
}
|
||||
|
||||
private static void DebugConfiguration(CommandArgs args)
|
||||
private static void ShowConfiguration(CommandArgs args)
|
||||
{
|
||||
args.Player.SendMessage("TShock Config:");
|
||||
string lineOne = string.Format("BanCheater : {0}, KickCheater : {1}, BanGriefer : {2}, KickGriefer : {3}",
|
||||
|
|
@ -1313,7 +1498,7 @@ namespace TShockAPI
|
|||
args.Player.SendMessage("Configuration reload complete. Some changes may require server restart.");
|
||||
}
|
||||
|
||||
private static void Password(CommandArgs args)
|
||||
private static void ServerPassword(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count != 1)
|
||||
{
|
||||
|
|
@ -1465,10 +1650,10 @@ namespace TShockAPI
|
|||
{
|
||||
foreach (Region r in TShock.Regions.Regions)
|
||||
{
|
||||
args.Player.SendMessage(r.RegionName + ": P: " + r.DisableBuild + " X: " + r.RegionArea.X + " Y: " + r.RegionArea.Y + " W: " + r.RegionArea.Width + " H: " + r.RegionArea.Height);
|
||||
foreach (int s in r.RegionAllowedIDs)
|
||||
args.Player.SendMessage(r.Name + ": P: " + r.DisableBuild + " X: " + r.Area.X + " Y: " + r.Area.Y + " W: " + r.Area.Width + " H: " + r.Area.Height);
|
||||
foreach (int s in r.AllowedIDs)
|
||||
{
|
||||
args.Player.SendMessage(r.RegionName + ": " + s);
|
||||
args.Player.SendMessage(r.Name + ": " + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1673,7 +1858,7 @@ namespace TShockAPI
|
|||
var nameslist = new List<string>();
|
||||
for (int i = 0; i < pagelimit && i + (page * pagelimit) < regions.Count; i++)
|
||||
{
|
||||
nameslist.Add(regions[i].RegionName);
|
||||
nameslist.Add(regions[i].Name);
|
||||
}
|
||||
|
||||
//convert the list to an array for joining
|
||||
|
|
@ -1918,8 +2103,8 @@ namespace TShockAPI
|
|||
else
|
||||
{
|
||||
var ply = players[0];
|
||||
args.Player.SendMessage("Annoying " + ply.Name + " for " + annoy.ToString() + " seconds.");
|
||||
(new Thread(new ParameterizedThreadStart(ply.Whoopie))).Start(annoy);
|
||||
args.Player.SendMessage("Annoying " + ply.Name + " for " + annoy + " seconds.");
|
||||
(new Thread(ply.Whoopie)).Start(annoy);
|
||||
}
|
||||
}
|
||||
#endregion General Commands
|
||||
|
|
@ -2010,7 +2195,7 @@ namespace TShockAPI
|
|||
if (itemAmount == 0 || itemAmount > item.maxStack)
|
||||
itemAmount = item.maxStack;
|
||||
args.Player.GiveItem(item.type, item.name, item.width, item.height, itemAmount);
|
||||
args.Player.SendMessage(string.Format("Gave {0} {1}(s).", itemAmount.ToString(), item.name));
|
||||
args.Player.SendMessage(string.Format("Gave {0} {1}(s).", itemAmount, item.name));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2080,8 +2265,8 @@ namespace TShockAPI
|
|||
if (itemAmount == 0 || itemAmount > item.maxStack)
|
||||
itemAmount = item.maxStack;
|
||||
plr.GiveItem(item.type, item.name, item.width, item.height, itemAmount);
|
||||
args.Player.SendMessage(string.Format("Gave {0} {1} {2}(s).", plr.Name, itemAmount.ToString(), item.name));
|
||||
plr.SendMessage(string.Format("{0} gave you {1} {2}(s).", args.Player.Name, itemAmount.ToString(), item.name));
|
||||
args.Player.SendMessage(string.Format("Gave {0} {1} {2}(s).", plr.Name, itemAmount, item.name));
|
||||
plr.SendMessage(string.Format("{0} gave you {1} {2}(s).", args.Player.Name, itemAmount, item.name));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ namespace TShockAPI
|
|||
public int DefaultMaximumSpawns = 4;
|
||||
public int DefaultSpawnRate = 700;
|
||||
public int ServerPort = 7777;
|
||||
public bool EnableWhitelist = false;
|
||||
public bool InfiniteInvasion = false;
|
||||
public bool AlwaysPvP = false;
|
||||
public bool EnableWhitelist;
|
||||
public bool InfiniteInvasion;
|
||||
public bool AlwaysPvP;
|
||||
public bool KickCheaters = true;
|
||||
public bool BanCheaters = true;
|
||||
public bool KickGriefers = true;
|
||||
|
|
@ -44,24 +44,24 @@ namespace TShockAPI
|
|||
public string DistributationAgent = "facepunch";
|
||||
public int MaxSlots = 8;
|
||||
public bool RangeChecks = true;
|
||||
public bool SpamChecks = false;
|
||||
public bool DisableBuild = false;
|
||||
public bool SpamChecks;
|
||||
public bool DisableBuild;
|
||||
public int TileThreshold = 60;
|
||||
|
||||
public float[] AdminChatRGB = { 255, 0, 0 };
|
||||
public float[] SuperAdminChatRGB = { 255, 0, 0 };
|
||||
public string AdminChatPrefix = "(Admin) ";
|
||||
public bool AdminChatEnabled = true;
|
||||
|
||||
public int PvpThrottle = 0;
|
||||
public int PvpThrottle;
|
||||
|
||||
public int BackupInterval = 0;
|
||||
public int BackupInterval;
|
||||
public int BackupKeepFor = 60;
|
||||
|
||||
public bool RememberLeavePos = false;
|
||||
public bool RememberLeavePos;
|
||||
|
||||
public bool HardcoreOnly = false;
|
||||
public bool KickOnHardcoreDeath = false;
|
||||
public bool BanOnHardcoreDeath = false;
|
||||
public bool HardcoreOnly;
|
||||
public bool KickOnHardcoreDeath;
|
||||
public bool BanOnHardcoreDeath;
|
||||
|
||||
public bool AutoSave = true;
|
||||
|
||||
|
|
@ -93,12 +93,25 @@ namespace TShockAPI
|
|||
public string TileKillAbuseReason = "Tile Kill abuse ({0})";
|
||||
public string HardcoreBanReason = "Death results in a ban";
|
||||
public string HardcoreKickReason = "Death results in a kick";
|
||||
public string ProjectileAbuseReason = "Projectile abuse";
|
||||
|
||||
public bool EnableDNSHostResolution = false;
|
||||
public bool EnableDNSHostResolution;
|
||||
|
||||
public bool EnableBanOnUsernames = false;
|
||||
public bool EnableBanOnUsernames;
|
||||
|
||||
public bool EnableAntiLag = true;
|
||||
|
||||
public string DefaultRegistrationGroupName = "default";
|
||||
|
||||
public bool DisableSpewLogs = true;
|
||||
|
||||
/// <summary>
|
||||
/// Valid types are "sha512", "sha256", "md5"
|
||||
/// </summary>
|
||||
public string HashAlgorithm = "sha512";
|
||||
|
||||
public bool BufferPackets = false;
|
||||
|
||||
public static ConfigFile Read(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011 The TShock Team
|
||||
|
||||
|
|
@ -17,12 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Community.CsharpSqlite.SQLiteClient;
|
||||
using TShockAPI.DB;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
|
|
@ -34,45 +31,38 @@ namespace TShockAPI.DB
|
|||
{
|
||||
database = db;
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
var table = new SqlTable("Bans",
|
||||
new SqlColumn("IP", MySqlDbType.String, 16) { Primary = true },
|
||||
new SqlColumn("Name", MySqlDbType.Text),
|
||||
new SqlColumn("Reason", MySqlDbType.Text)
|
||||
);
|
||||
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "bans.txt");
|
||||
if (File.Exists(file))
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS 'Bans' ('IP' TEXT PRIMARY KEY, 'Name' TEXT, 'Reason' TEXT);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS Bans (IP VARCHAR(255) PRIMARY, Name VARCHAR(255), Reason VARCHAR(255));";
|
||||
|
||||
com.ExecuteNonQuery();
|
||||
|
||||
String file = Path.Combine( TShock.SavePath, "bans.txt" );
|
||||
if (File.Exists(file))
|
||||
using (StreamReader sr = new StreamReader(file))
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(file))
|
||||
String line;
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
String line;
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
String[] info = line.Split('|');
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO Bans (IP, Name, Reason) VALUES (@ip, @name, @reason);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO Bans SET IP=@ip, Name=@name, Reason=@reason;";
|
||||
com.AddParameter("@ip", info[0].Trim());
|
||||
com.AddParameter("@name", info[1].Trim());
|
||||
com.AddParameter("@reason", info[2].Trim());
|
||||
com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
}
|
||||
String[] info = line.Split('|');
|
||||
string query;
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
query = "INSERT OR IGNORE INTO Bans (IP, Name, Reason) VALUES (@0, @1, @2);";
|
||||
else
|
||||
query = "INSERT IGNORE INTO Bans SET IP=@0, Name=@1, Reason=@2;";
|
||||
db.Query(query, info[0].Trim(), info[1].Trim(), info[2].Trim());
|
||||
}
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "bans.txt");
|
||||
if (!Directory.Exists(path))
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
}
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "bans.txt");
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,17 +70,10 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Bans WHERE IP=@0", ip))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Bans WHERE IP=@ip";
|
||||
com.AddParameter("@ip", ip);
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
return new Ban((string)reader["IP"], (string)reader["Name"], (string)reader["Reason"]);
|
||||
|
||||
reader.Close();
|
||||
}
|
||||
if (reader.Read())
|
||||
return new Ban(reader.Get<string>("IP"), reader.Get<string>("Name"), reader.Get<string>("Reason"));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -108,20 +91,14 @@ namespace TShockAPI.DB
|
|||
}
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
var namecol = casesensitive ? "Name" : "UPPER(Name)";
|
||||
if (!casesensitive)
|
||||
name = name.ToUpper();
|
||||
using (var reader = database.QueryReader("SELECT * FROM Bans WHERE " + namecol + "=@0", name))
|
||||
{
|
||||
var namecol = casesensitive ? "Name" : "UPPER(Name)";
|
||||
if (!casesensitive)
|
||||
name = name.ToUpper();
|
||||
com.CommandText = "SELECT * FROM Bans WHERE " + namecol + "=@name";
|
||||
com.AddParameter("@name", name);
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
return new Ban((string)reader["IP"], (string)reader["Name"], (string)reader["Reason"]);
|
||||
if (reader.Read())
|
||||
return new Ban(reader.Get<string>("IP"), reader.Get<string>("Name"), reader.Get<string>("Reason"));
|
||||
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -135,15 +112,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "INSERT INTO Bans (IP, Name, Reason) VALUES (@ip, @name, @reason);";
|
||||
com.AddParameter("@ip", ip);
|
||||
com.AddParameter("@name", name);
|
||||
com.AddParameter("@reason", reason);
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
return true;
|
||||
return database.Query("INSERT INTO Bans (IP, Name, Reason) VALUES (@0, @1, @2);", ip, name, reason) != 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -156,13 +125,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "DELETE FROM Bans WHERE IP=@ip";
|
||||
com.AddParameter("@ip", ip);
|
||||
com.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
return database.Query("DELETE FROM Bans WHERE IP=@0", ip) != 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -174,12 +137,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "DELETE FROM Bans";
|
||||
com.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
return database.Query("DELETE FROM Bans") != 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public static class DbExt
|
||||
{
|
||||
public static IDbDataParameter AddParameter(this IDbCommand command, string name, object data)
|
||||
{
|
||||
var parm = command.CreateParameter();
|
||||
parm.ParameterName = name;
|
||||
parm.Value = data;
|
||||
command.Parameters.Add(parm);
|
||||
return parm;
|
||||
}
|
||||
|
||||
static Dictionary<Type, Func<IDataReader, int, object>> ReadFuncs = new Dictionary<Type, Func<IDataReader, int, object>>()
|
||||
{
|
||||
{typeof(bool), (s, i) => s.GetBoolean(i)},
|
||||
{typeof(byte), (s, i) => s.GetByte(i)},
|
||||
{typeof(Int16), (s, i) => s.GetInt16(i)},
|
||||
{typeof(Int32), (s, i) => s.GetInt32(i)},
|
||||
{typeof(Int64), (s, i) => s.GetInt64(i)},
|
||||
{typeof(string), (s, i) => s.GetString(i)},
|
||||
{typeof(decimal), (s, i) => s.GetDecimal(i)},
|
||||
{typeof(float), (s, i) => s.GetFloat(i)},
|
||||
{typeof(double), (s, i) => s.GetDouble(i)},
|
||||
};
|
||||
|
||||
public static T Get<T>(this IDataReader reader, string column)
|
||||
{
|
||||
return reader.Get<T>(reader.GetOrdinal(column));
|
||||
}
|
||||
|
||||
public static T Get<T>(this IDataReader reader, int column)
|
||||
{
|
||||
if (ReadFuncs.ContainsKey(typeof(T)))
|
||||
return (T)ReadFuncs[typeof(T)](reader, column);
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using Community.CsharpSqlite.SQLiteClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
|
|
@ -18,17 +17,13 @@ namespace TShockAPI.DB
|
|||
{
|
||||
database = db;
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS 'GroupList' ('GroupName' TEXT PRIMARY KEY, 'Commands' TEXT, 'OrderBy' TEXT);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS GroupList (GroupName VARCHAR(255) PRIMARY, Commands VARCHAR(255), OrderBy VARCHAR(255));";
|
||||
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
var table = new SqlTable("GroupList",
|
||||
new SqlColumn("GroupName", MySqlDbType.VarChar, 32) { Primary = true },
|
||||
new SqlColumn("Commands", MySqlDbType.Text),
|
||||
new SqlColumn("ChatColor", MySqlDbType.Text)
|
||||
);
|
||||
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
|
||||
//Add default groups
|
||||
AddGroup("trustedadmin", "admin,maintenance,cfg,butcher,item,heal,immunetoban,ignorecheatdetection,ignoregriefdetection,usebanneditem,manageusers");
|
||||
|
|
@ -50,35 +45,28 @@ namespace TShockAPI.DB
|
|||
String[] info = line.Split(' ');
|
||||
String comms = "";
|
||||
int size = info.Length;
|
||||
int test = 0;
|
||||
bool hasOrder = int.TryParse(info[info.Length - 1], out test);
|
||||
if (hasOrder)
|
||||
size = info.Length - 1;
|
||||
for (int i = 1; i < size; i++)
|
||||
{
|
||||
if (!comms.Equals(""))
|
||||
comms = comms + ",";
|
||||
comms = comms + info[i].Trim();
|
||||
}
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO GroupList (GroupName, Commands, OrderBy) VALUES (@groupname, @commands, @order);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO GroupList SET GroupName=@groupname, Commands=@commands, OrderBy=@order;";
|
||||
|
||||
com.AddParameter("@groupname", info[0].Trim());
|
||||
com.AddParameter("@commands", comms);
|
||||
com.AddParameter("@order", hasOrder ? info[info.Length - 1] : "0");
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
string query = "";
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
query = "INSERT OR IGNORE INTO GroupList (GroupName, Commands) VALUES (@0, @1);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
query = "INSERT IGNORE INTO GroupList SET GroupName=@0, Commands=@1;";
|
||||
|
||||
db.Query(query, info[0].Trim(), comms);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "groups.txt");
|
||||
if (!Directory.Exists(path))
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
|
|
@ -86,27 +74,6 @@ namespace TShockAPI.DB
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds group with name and permissions if it does not exist.
|
||||
/// </summary>
|
||||
/// <param name="name">name of group</param>
|
||||
/// <param name="commands">permissions</param>
|
||||
public void AddGroup(string name, string commands)
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText =
|
||||
"INSERT OR IGNORE INTO GroupList (GroupName, Commands, OrderBy) VALUES (@groupname, @commands, @order);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText =
|
||||
"INSERT IGNORE INTO GroupList SET GroupName=@groupname, Commands=@commands, OrderBy=@order;";
|
||||
com.AddParameter("@groupname", name);
|
||||
com.AddParameter("@commands", commands);
|
||||
com.AddParameter("@order", "0");
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public bool GroupExists(string group)
|
||||
{
|
||||
|
|
@ -123,93 +90,72 @@ namespace TShockAPI.DB
|
|||
return false;
|
||||
}
|
||||
|
||||
public String addGroup(String name, String permissions)
|
||||
/// <summary>
|
||||
/// Adds group with name and permissions if it does not exist.
|
||||
/// </summary>
|
||||
/// <param name="name">name of group</param>
|
||||
/// <param name="permissions">permissions</param>
|
||||
public String AddGroup(String name, String permissions, String ChatColor = "255,255,255")
|
||||
{
|
||||
String message = "";
|
||||
if( GroupExists( name ) )
|
||||
if (GroupExists(name))
|
||||
return "Error: Group already exists. Use /modGroup to change permissions.";
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO GroupList (GroupName, Commands, OrderBy) VALUES (@groupname, @commands, @order);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO GroupList SET GroupName=@groupname, Commands=@commands, OrderBy=@order;";
|
||||
com.AddParameter("@groupname", name);
|
||||
com.AddParameter("@commands", permissions);
|
||||
com.AddParameter("@order", "0");
|
||||
if (com.ExecuteNonQuery() == 1)
|
||||
message = "Group " + name + " has been created successfully.";
|
||||
Group g = new Group(name);
|
||||
g.permissions.Add(permissions);
|
||||
groups.Add(g);
|
||||
}
|
||||
|
||||
string query = (TShock.Config.StorageType.ToLower() == "sqlite") ?
|
||||
"INSERT OR IGNORE INTO GroupList (GroupName, Commands, ChatColor) VALUES (@0, @1, @2);" :
|
||||
"INSERT IGNORE INTO GroupList SET GroupName=@0, Commands=@1";
|
||||
if (database.Query(query, name, permissions, ChatColor) == 1)
|
||||
message = "Group " + name + " has been created successfully.";
|
||||
Group g = new Group(name, null, ChatColor);
|
||||
g.permissions.Add(permissions);
|
||||
groups.Add(g);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public String delGroup(String name)
|
||||
public String DeleteGroup(String name)
|
||||
{
|
||||
String message = "";
|
||||
if (!GroupExists(name))
|
||||
return "Error: Group doesn't exists.";
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "Delete FROM GroupList WHERE GroupName=@groupname;";
|
||||
com.AddParameter("@groupname", name);
|
||||
if (com.ExecuteNonQuery() == 1)
|
||||
message = "Group " + name + " has been deleted successfully.";
|
||||
groups.Remove(Tools.GetGroup(name));
|
||||
}
|
||||
|
||||
if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1)
|
||||
message = "Group " + name + " has been deleted successfully.";
|
||||
groups.Remove(Tools.GetGroup(name));
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public String addPermission(String name, List<String> permissions)
|
||||
public String AddPermissions(String name, List<String> permissions)
|
||||
{
|
||||
String message = "";
|
||||
if (!GroupExists(name))
|
||||
return "Error: Group doesn't exists.";
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
Group g = Tools.GetGroup(name);
|
||||
List<String> perm = g.permissions;
|
||||
foreach (String p in permissions)
|
||||
{
|
||||
if (!perm.Contains(p))
|
||||
{
|
||||
if (perm.Count > 0 && perm[0].Equals(""))
|
||||
perm[0] = p;
|
||||
else
|
||||
g.permissions.Add(p);
|
||||
}
|
||||
}
|
||||
com.CommandText = "UPDATE GroupList SET Commands=@perm WHERE GroupName=@name;";
|
||||
com.AddParameter("@perm", String.Join(",", perm));
|
||||
com.AddParameter("@name", name);
|
||||
if (com.ExecuteNonQuery() == 1)
|
||||
message = "Group " + name + " has been modified successfully.";
|
||||
}
|
||||
|
||||
var group = Tools.GetGroup(name);
|
||||
//Add existing permissions (without duplicating)
|
||||
permissions.AddRange(group.permissions.Where(s => !permissions.Contains(s)));
|
||||
|
||||
if (database.Query("UPDATE GroupList SET Commands=@0 WHERE GroupName=@1", String.Join(",", permissions), name) != 0)
|
||||
message = "Group " + name + " has been modified successfully.";
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public String delPermission(String name, List<String> permissions)
|
||||
public String DeletePermissions(String name, List<String> permissions)
|
||||
{
|
||||
String message = "";
|
||||
if (!GroupExists(name))
|
||||
return "Error: Group doesn't exists.";
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
Group g = Tools.GetGroup(name);
|
||||
List<String> perm = g.permissions;
|
||||
foreach (String p in permissions)
|
||||
{
|
||||
if (perm.Contains(p))
|
||||
g.permissions.Remove(p);
|
||||
}
|
||||
com.CommandText = "UPDATE GroupList SET Commands=@perm WHERE GroupName=@name;";
|
||||
com.AddParameter("@perm", String.Join(",", perm));
|
||||
com.AddParameter("@name", name);
|
||||
if (com.ExecuteNonQuery() == 1)
|
||||
message = "Group " + name + " has been modified successfully.";
|
||||
}
|
||||
|
||||
var group = Tools.GetGroup(name);
|
||||
|
||||
//Only get permissions that exist in the group.
|
||||
var newperms = permissions.Where(s => group.permissions.Contains(s));
|
||||
|
||||
if (database.Query("UPDATE GroupList SET Commands=@0 WHERE GroupName=@1", String.Join(",", newperms), name) != 0)
|
||||
message = "Group " + name + " has been modified successfully.";
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
|
@ -220,41 +166,29 @@ namespace TShockAPI.DB
|
|||
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Grouplist"))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Grouplist;";
|
||||
using (var reader = com.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Group group = null;
|
||||
string groupname = reader.Get<String>("GroupName");
|
||||
group = new Group(groupname);
|
||||
Group group = null;
|
||||
string groupname = reader.Get<String>("GroupName");
|
||||
group = new Group(groupname);
|
||||
|
||||
//Inherit Given commands
|
||||
String[] commands = reader.Get<String>("Commands").Split(',');
|
||||
for (int i = 0; i < commands.Length; i++)
|
||||
{
|
||||
group.AddPermission(commands[i].Trim());
|
||||
}
|
||||
groups.Add(group);
|
||||
}
|
||||
}
|
||||
/** ORDER BY IS DUMB
|
||||
//Inherit all commands from group below in order, unless Order is 0 (unique groups anyone)
|
||||
foreach (Group group in groups)
|
||||
{
|
||||
if (group.Order != 0 && group.Order < groups.Count)
|
||||
//Inherit Given commands
|
||||
String[] commands = reader.Get<String>("Commands").Split(',');
|
||||
for (int i = 0; i < commands.Length; i++)
|
||||
{
|
||||
for (int i = group.Order + 1; i < groups.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < groups[i].permissions.Count; j++)
|
||||
{
|
||||
group.AddPermission(groups[i].permissions[j]);
|
||||
}
|
||||
}
|
||||
group.AddPermission(commands[i].Trim());
|
||||
}
|
||||
}*/
|
||||
String[] chatcolour = (reader.Get<String>("ChatColor") ?? "").Split(',');
|
||||
if (chatcolour.Length == 3)
|
||||
{
|
||||
byte.TryParse(chatcolour[0], out group.R);
|
||||
byte.TryParse(chatcolour[1], out group.G);
|
||||
byte.TryParse(chatcolour[2], out group.B);
|
||||
}
|
||||
groups.Add(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
256
TShockAPI/DB/IQueryBuilder.cs
Normal file
256
TShockAPI/DB/IQueryBuilder.cs
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MySql.Data.MySqlClient;
|
||||
using TShockAPI.Extensions;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public interface IQueryBuilder
|
||||
{
|
||||
string CreateTable(SqlTable table);
|
||||
string AlterTable(SqlTable from, SqlTable to);
|
||||
string DbTypeToString(MySqlDbType type, int? length);
|
||||
string UpdateValue(string table, List<SqlValue> values, List<SqlValue> wheres);
|
||||
string InsertValues(string table, List<SqlValue> values);
|
||||
string ReadColumn(string table, List<SqlValue> wheres);
|
||||
}
|
||||
|
||||
public class SqliteQueryCreator : IQueryBuilder
|
||||
{
|
||||
public string CreateTable(SqlTable table)
|
||||
{
|
||||
var columns = table.Columns.Select(c => "'{0}' {1} {2} {3} {4}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", c.AutoIncrement ? "AUTOINCREMENT" : "", c.NotNull ? "NOT NULL" : "", c.Unique ? "UNIQUE" : ""));
|
||||
return "CREATE TABLE '{0}' ({1})".SFormat(table.Name, string.Join(", ", columns));
|
||||
}
|
||||
static Random rand = new Random();
|
||||
/// <summary>
|
||||
/// Alter a table from source to destination
|
||||
/// </summary>
|
||||
/// <param name="from">Must have name and column names. Column types are not required</param>
|
||||
/// <param name="to">Must have column names and column types.</param>
|
||||
/// <returns></returns>
|
||||
public string AlterTable(SqlTable from, SqlTable to)
|
||||
{
|
||||
var rstr = rand.NextString(20);
|
||||
var alter = "ALTER TABLE '{0}' RENAME TO '{1}_{0}'".SFormat(from.Name, rstr);
|
||||
var create = CreateTable(to);
|
||||
//combine all columns in the 'from' variable excluding ones that aren't in the 'to' variable.
|
||||
//exclude the ones that aren't in 'to' variable because if the column is deleted, why try to import the data?
|
||||
var insert = "INSERT INTO '{0}' ({1}) SELECT {1} FROM {2}_{0}".SFormat(from.Name, string.Join(", ", from.Columns.Where(c => to.Columns.Any(c2 => c2.Name == c.Name)).Select(c => c.Name)), rstr);
|
||||
var drop = "DROP TABLE '{0}_{1}'".SFormat(rstr, from.Name);
|
||||
return "{0}; {1}; {2}; {3};".SFormat(alter, create, insert, drop);
|
||||
/*
|
||||
ALTER TABLE "main"."Bans" RENAME TO "oXHFcGcd04oXHFcGcd04_Bans"
|
||||
CREATE TABLE "main"."Bans" ("IP" TEXT PRIMARY KEY ,"Name" TEXT)
|
||||
INSERT INTO "main"."Bans" SELECT "IP","Name" FROM "main"."oXHFcGcd04oXHFcGcd04_Bans"
|
||||
DROP TABLE "main"."oXHFcGcd04oXHFcGcd04_Bans"
|
||||
*
|
||||
* Twitchy - Oh. I get it!
|
||||
*/
|
||||
}
|
||||
public string UpdateValue(string table, List<SqlValue> values, List<SqlValue> wheres)
|
||||
{
|
||||
var sbvalues = new StringBuilder();
|
||||
var sbwheres = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (SqlValue value in values)
|
||||
{
|
||||
sbvalues.Append(value.Name + "=" + value.Value.ToString());
|
||||
if (count != values.Count - 1)
|
||||
sbvalues.Append(",");
|
||||
count++;
|
||||
}
|
||||
count = 0;
|
||||
foreach (SqlValue where in wheres)
|
||||
{
|
||||
sbwheres.Append(where.Name + "=" + where.Value.ToString());
|
||||
if (count != wheres.Count - 1)
|
||||
sbvalues.Append(" AND ");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (wheres.Count > 0)
|
||||
return "UPDATE '{0}' SET {1} WHERE {2}".SFormat(table, sbvalues.ToString(), sbwheres.ToString());
|
||||
else
|
||||
return "UPDATE '{0}' SET {1}".SFormat(table, sbvalues.ToString());
|
||||
}
|
||||
public string InsertValues(string table, List<SqlValue> values)
|
||||
{
|
||||
var sbnames = new StringBuilder();
|
||||
var sbvalues = new StringBuilder();
|
||||
int count = 0;
|
||||
|
||||
foreach (SqlValue name in values)
|
||||
{
|
||||
sbnames.Append(name.Name);
|
||||
|
||||
if (count != values.Count - 1)
|
||||
sbnames.Append(", ");
|
||||
count++;
|
||||
}
|
||||
count = 0;
|
||||
foreach (SqlValue value in values)
|
||||
{
|
||||
sbvalues.Append(value.Value.ToString());
|
||||
if (count != values.Count - 1)
|
||||
sbvalues.Append(", ");
|
||||
count++;
|
||||
}
|
||||
|
||||
return "INSERT INTO '{0}' ({1}) VALUES ({2})".SFormat(table, sbnames.ToString(), sbvalues.ToString());
|
||||
}
|
||||
public string ReadColumn(string table, List<SqlValue> wheres)
|
||||
{
|
||||
var sbwheres = new StringBuilder();
|
||||
int count = 0;
|
||||
|
||||
foreach (SqlValue where in wheres)
|
||||
{
|
||||
sbwheres.Append(where.Name + "=" + where.Value.ToString());
|
||||
if (count != wheres.Count - 1)
|
||||
sbwheres.Append(" AND ");
|
||||
count++;
|
||||
}
|
||||
|
||||
if(wheres.Count > 0)
|
||||
return "SELECT * FROM {0} WHERE {1}".SFormat(table, sbwheres.ToString());
|
||||
else
|
||||
return "SELECT * FROM {0}".SFormat(table);
|
||||
}
|
||||
|
||||
static readonly Dictionary<MySqlDbType, string> TypesAsStrings = new Dictionary<MySqlDbType, string>
|
||||
{
|
||||
{MySqlDbType.VarChar, "TEXT"},
|
||||
{MySqlDbType.String, "TEXT"},
|
||||
{MySqlDbType.Text, "TEXT"},
|
||||
{MySqlDbType.TinyText, "TEXT"},
|
||||
{MySqlDbType.MediumText, "TEXT"},
|
||||
{MySqlDbType.LongText, "TEXT"},
|
||||
{MySqlDbType.Int32, "INTEGER"},
|
||||
};
|
||||
public string DbTypeToString(MySqlDbType type, int? length)
|
||||
{
|
||||
string ret;
|
||||
if (TypesAsStrings.TryGetValue(type, out ret))
|
||||
return ret;
|
||||
throw new NotImplementedException(Enum.GetName(typeof(MySqlDbType), type));
|
||||
}
|
||||
}
|
||||
public class MysqlQueryCreator : IQueryBuilder
|
||||
{
|
||||
public string CreateTable(SqlTable table)
|
||||
{
|
||||
var columns = table.Columns.Select(c => "{0} {1} {2} {3}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", c.AutoIncrement ? "AUTOINCREMENT" : "", c.NotNull ? "NOT NULL" : ""));
|
||||
var uniques = table.Columns.Where(c => c.Unique).Select(c => c.Name);
|
||||
return "CREATE TABLE {0} ({1}) {2}".SFormat(table.Name, string.Join(", ", columns), uniques.Count() > 0 ? ", UNIQUE({0})".SFormat(string.Join(", ", uniques)) : "");
|
||||
}
|
||||
static Random rand = new Random();
|
||||
/// <summary>
|
||||
/// Alter a table from source to destination
|
||||
/// </summary>
|
||||
/// <param name="from">Must have name and column names. Column types are not required</param>
|
||||
/// <param name="to">Must have column names and column types.</param>
|
||||
/// <returns></returns>
|
||||
public string AlterTable(SqlTable from, SqlTable to)
|
||||
{
|
||||
var rstr = rand.NextString(20);
|
||||
var alter = "RENAME TABLE {0} TO {1}_{0}".SFormat(from.Name, rstr);
|
||||
var create = CreateTable(to);
|
||||
//combine all columns in the 'from' variable excluding ones that aren't in the 'to' variable.
|
||||
//exclude the ones that aren't in 'to' variable because if the column is deleted, why try to import the data?
|
||||
var insert = "INSERT INTO {0} ({1}) SELECT {1} FROM {2}_{0}".SFormat(from.Name, string.Join(", ", from.Columns.Where(c => to.Columns.Any(c2 => c2.Name == c.Name)).Select(c => c.Name)), rstr);
|
||||
var drop = "DROP TABLE {0}_{1}".SFormat(rstr, from.Name);
|
||||
return "{0}; {1}; {2}; {3};".SFormat(alter, create, insert, drop);
|
||||
}
|
||||
public string UpdateValue(string table, List<SqlValue> values, List<SqlValue> wheres)
|
||||
{
|
||||
var sbvalues = new StringBuilder();
|
||||
var sbwheres = new StringBuilder();
|
||||
int count = 0;
|
||||
foreach (SqlValue value in values)
|
||||
{
|
||||
sbvalues.Append(value.Name + "=" + value.Value.ToString());
|
||||
if (count != values.Count - 1)
|
||||
sbvalues.Append("AND");
|
||||
count++;
|
||||
}
|
||||
count = 0;
|
||||
foreach (SqlValue where in wheres)
|
||||
{
|
||||
sbwheres.Append(where.Name + "=" + where.Value.ToString());
|
||||
if (count != wheres.Count - 1)
|
||||
sbvalues.Append(" AND ");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (wheres.Count > 0)
|
||||
return "UPDATE {0} SET {1} WHERE {2}".SFormat(table, sbvalues.ToString(), sbwheres.ToString());
|
||||
else
|
||||
return "UPDATE {0} SET {1}".SFormat(table, sbvalues.ToString());
|
||||
}
|
||||
public string InsertValues(string table, List<SqlValue> values)
|
||||
{
|
||||
var sbnames = new StringBuilder();
|
||||
var sbvalues = new StringBuilder();
|
||||
int count = 0;
|
||||
|
||||
foreach (SqlValue name in values)
|
||||
{
|
||||
sbnames.Append(name.Name);
|
||||
|
||||
if (count != values.Count - 1)
|
||||
sbnames.Append(", ");
|
||||
count++;
|
||||
}
|
||||
count = 0;
|
||||
foreach (SqlValue value in values)
|
||||
{
|
||||
sbvalues.Append(value.Value.ToString());
|
||||
if (count != values.Count - 1)
|
||||
sbvalues.Append(", ");
|
||||
count++;
|
||||
}
|
||||
|
||||
return "INSERT INTO {0} ({1}) VALUES ({2})".SFormat(table, sbnames.ToString(), sbvalues.ToString());
|
||||
}
|
||||
public string ReadColumn(string table, List<SqlValue> wheres)
|
||||
{
|
||||
var sbwheres = new StringBuilder();
|
||||
int count = 0;
|
||||
|
||||
foreach (SqlValue where in wheres)
|
||||
{
|
||||
sbwheres.Append(where.Name + "=" + where.Value.ToString());
|
||||
if (count != wheres.Count - 1)
|
||||
sbwheres.Append(" AND ");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (wheres.Count > 0)
|
||||
return "SELECT * FROM {0} WHERE {1}".SFormat(table, sbwheres.ToString());
|
||||
else
|
||||
return "SELECT * FROM {0}".SFormat(table);
|
||||
}
|
||||
|
||||
static readonly Dictionary<MySqlDbType, string> TypesAsStrings = new Dictionary<MySqlDbType, string>
|
||||
{
|
||||
{MySqlDbType.VarChar, "VARCHAR"},
|
||||
{MySqlDbType.String, "CHAR"},
|
||||
{MySqlDbType.Text, "TEXT"},
|
||||
{MySqlDbType.TinyText, "TINYTEXT"},
|
||||
{MySqlDbType.MediumText, "MEDIUMTEXT"},
|
||||
{MySqlDbType.LongText, "LONGTEXT"},
|
||||
{MySqlDbType.Int32, "INT"},
|
||||
};
|
||||
public string DbTypeToString(MySqlDbType type, int? length)
|
||||
{
|
||||
string ret;
|
||||
if (TypesAsStrings.TryGetValue(type, out ret))
|
||||
return ret + (length != null ? "({0})".SFormat((int)length) : "");
|
||||
throw new NotImplementedException(Enum.GetName(typeof(MySqlDbType), type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using Community.CsharpSqlite.SQLiteClient;
|
||||
using TShockAPI.DB;
|
||||
using System.IO;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
|
|
@ -18,48 +15,42 @@ namespace TShockAPI.DB
|
|||
{
|
||||
database = db;
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
var table = new SqlTable("ItemBans",
|
||||
new SqlColumn("ItemName", MySqlDbType.VarChar, 50) { Primary = true }
|
||||
);
|
||||
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "itembans.txt");
|
||||
if (File.Exists(file))
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS 'ItemBans' ('ItemName' TEXT PRIMARY KEY);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS ItemBans (ItemName VARCHAR(255) PRIMARY);";
|
||||
com.ExecuteNonQuery();
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "itembans.txt");
|
||||
if (File.Exists(file))
|
||||
using (StreamReader sr = new StreamReader(file))
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(file))
|
||||
String line;
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
String line;
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
if (!line.Equals("") && !line.Substring(0, 1).Equals("#"))
|
||||
{
|
||||
if (!line.Equals("") && !line.Substring(0, 1).Equals("#"))
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO 'ItemBans' (ItemName) VALUES (@name);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO ItemBans SET ItemName=@name;";
|
||||
|
||||
int id = 0;
|
||||
int.TryParse(line, out id);
|
||||
com.AddParameter("@name", Tools.GetItemById(id).name);
|
||||
com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
}
|
||||
string query = (TShock.Config.StorageType.ToLower() == "sqlite") ?
|
||||
"INSERT OR IGNORE INTO 'ItemBans' (ItemName) VALUES (@0);" :
|
||||
"INSERT IGNORE INTO ItemBans SET ItemName=@0;";
|
||||
|
||||
int id = 0;
|
||||
int.TryParse(line, out id);
|
||||
|
||||
database.Query(query, Tools.GetItemById(id).name);
|
||||
}
|
||||
}
|
||||
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "itembans.txt");
|
||||
if (!Directory.Exists(path))
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
}
|
||||
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "itembans.txt");
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
}
|
||||
|
||||
UpdateItemBans();
|
||||
|
|
@ -68,29 +59,20 @@ namespace TShockAPI.DB
|
|||
public void UpdateItemBans()
|
||||
{
|
||||
ItemBans.Clear();
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "SELECT * FROM ItemBans";
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader!=null&&reader.Read())
|
||||
ItemBans.Add(reader.Get<string>("ItemName"));
|
||||
}
|
||||
using (var reader = database.QueryReader("SELECT * FROM ItemBans"))
|
||||
{
|
||||
while (reader != null && reader.Read())
|
||||
ItemBans.Add(reader.Get<string>("ItemName"));
|
||||
}
|
||||
}
|
||||
public void AddNewBan(string itemname = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "INSERT INTO ItemBans (ItemName) VALUES (@itemname);";
|
||||
com.AddParameter("@itemname", Tools.GetItemByName(itemname)[0].name);
|
||||
com.ExecuteNonQuery();
|
||||
if( !ItemIsBanned( itemname ) )
|
||||
ItemBans.Add(itemname);
|
||||
}
|
||||
database.Query("INSERT INTO ItemBans (ItemName) VALUES (@0);", Tools.GetItemByName(itemname)[0].name);
|
||||
if (!ItemIsBanned(itemname))
|
||||
ItemBans.Add(itemname);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -104,13 +86,8 @@ namespace TShockAPI.DB
|
|||
return;
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "Delete FROM 'ItemBans' WHERE ItemName=@itemname;";
|
||||
com.AddParameter("@itemname", Tools.GetItemByName(itemname)[0].name);
|
||||
com.ExecuteNonQuery();
|
||||
ItemBans.Remove(itemname);
|
||||
}
|
||||
database.Query("Delete FROM 'ItemBans' WHERE ItemName=@0;", Tools.GetItemByName(itemname)[0].name);
|
||||
ItemBans.Remove(itemname);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011 The TShock Team
|
||||
|
||||
|
|
@ -18,17 +18,13 @@ 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 System.IO;
|
||||
using System.Data;
|
||||
using TShockAPI.DB;
|
||||
using Community.CsharpSqlite.SQLiteClient;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Terraria;
|
||||
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class RegionManager
|
||||
|
|
@ -41,186 +37,119 @@ namespace TShockAPI.DB
|
|||
{
|
||||
database = db;
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
var table = new SqlTable("Regions",
|
||||
new SqlColumn("X1", MySqlDbType.Int32),
|
||||
new SqlColumn("Y1", MySqlDbType.Int32),
|
||||
new SqlColumn("height", MySqlDbType.Int32),
|
||||
new SqlColumn("width", MySqlDbType.Int32),
|
||||
new SqlColumn("RegionName", MySqlDbType.VarChar, 50) { Primary = true },
|
||||
new SqlColumn("WorldID", MySqlDbType.Text),
|
||||
new SqlColumn("UserIds", MySqlDbType.Text),
|
||||
new SqlColumn("Protected", MySqlDbType.Int32)
|
||||
);
|
||||
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
|
||||
ImportOld();
|
||||
|
||||
}
|
||||
|
||||
public void ImportOld()
|
||||
{
|
||||
String file = Path.Combine(TShock.SavePath, "regions.xml");
|
||||
if (!File.Exists(file))
|
||||
return;
|
||||
|
||||
Region region;
|
||||
Rectangle rect;
|
||||
using (var sr = new StreamReader(file))
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS 'Regions' ('X1' NUMERIC, 'Y1' NUMERIC, 'height' NUMERIC, 'width' NUMERIC, 'RegionName' TEXT PRIMARY KEY, 'WorldID' TEXT, 'UserIds' TEXT, 'Protected' NUMERIC);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS Regions (X1 INT(11), Y1 INT(11), height INT(11), width INT(11), RegionName VARCHAR(255) PRIMARY, WorldID VARCHAR(255), UserIds VARCHAR(255), Protected INT(1));";
|
||||
|
||||
com.ExecuteNonQuery();
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "regions.xml");
|
||||
String name = "";
|
||||
String world = "";
|
||||
int x1 = 0;
|
||||
int x2 = 0;
|
||||
int y1 = 0;
|
||||
int y2 = 0;
|
||||
int prot = 0;
|
||||
int users = 0;
|
||||
String[] ips;
|
||||
String ipstr = "";
|
||||
int updates = 0;
|
||||
if (File.Exists(file))
|
||||
using (var reader = XmlReader.Create(sr))
|
||||
{
|
||||
XmlReader reader;
|
||||
reader = XmlReader.Create(new StreamReader(file));
|
||||
// Parse the file and display each of the nodes.
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.NodeType)
|
||||
if (reader.NodeType != XmlNodeType.Element || reader.Name != "ProtectedRegion")
|
||||
continue;
|
||||
|
||||
region = new Region();
|
||||
rect = new Rectangle();
|
||||
|
||||
bool endregion = false;
|
||||
while (reader.Read() && !endregion)
|
||||
{
|
||||
case XmlNodeType.Element:
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "ProtectedRegion":
|
||||
name = "";
|
||||
world = "";
|
||||
x1 = 0;
|
||||
x2 = 0;
|
||||
y1 = 0;
|
||||
y2 = 0;
|
||||
prot = 0;
|
||||
users = 0;
|
||||
ips = null;
|
||||
ipstr = "";
|
||||
break;
|
||||
case "RegionName":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
name = reader.Value;
|
||||
break;
|
||||
case "Point1X":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out x1);
|
||||
break;
|
||||
case "Point1Y":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out y1);
|
||||
break;
|
||||
case "Point2X":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out x2);
|
||||
break;
|
||||
case "Point2Y":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out y2);
|
||||
break;
|
||||
case "Protected":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
if (reader.Value.Equals("True"))
|
||||
{
|
||||
prot = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
prot = 1;
|
||||
}
|
||||
break;
|
||||
case "WorldName":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
world = reader.Value;
|
||||
break;
|
||||
case "AllowedUserCount":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out users);
|
||||
if (users > 0)
|
||||
{
|
||||
ips = new String[users];
|
||||
for (int i = 0; i < users; i++)
|
||||
{
|
||||
do
|
||||
reader.Read();
|
||||
while (reader.NodeType != XmlNodeType.Text);
|
||||
ips[i] = reader.Value;
|
||||
}
|
||||
ipstr = "";
|
||||
for (int i = 0; i < ips.Length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ipstr != "")
|
||||
ipstr += ",";
|
||||
ipstr += TShock.Users.GetUserID(ips[i]);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Log.Error("An IP address failed to import. It wasn't a user in the new user system.");
|
||||
}
|
||||
if (reader.NodeType != XmlNodeType.Element)
|
||||
continue;
|
||||
|
||||
}
|
||||
string name = reader.Name;
|
||||
|
||||
}
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO Regions VALUES (@tx, @ty, @height, @width, @name, @worldid, @userids, @protected);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO Regions SET X1=@tx, Y1=@ty, height=@height, width=@width, RegionName=@name, WorldID=@world, UserIds=@userids, Protected=@protected;";
|
||||
com.AddParameter("@tx", x1);
|
||||
com.AddParameter("@ty", y1);
|
||||
com.AddParameter("@width", x2);
|
||||
com.AddParameter("@height", y2);
|
||||
com.AddParameter("@name", name);
|
||||
com.AddParameter("@worldid", world);
|
||||
com.AddParameter("@userids", ipstr);
|
||||
com.AddParameter("@protected", prot);
|
||||
updates += com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.Text:
|
||||
while (reader.Read() && reader.NodeType != XmlNodeType.Text) ;
|
||||
|
||||
break;
|
||||
case XmlNodeType.XmlDeclaration:
|
||||
case XmlNodeType.ProcessingInstruction:
|
||||
break;
|
||||
case XmlNodeType.Comment:
|
||||
break;
|
||||
case XmlNodeType.EndElement:
|
||||
switch (name)
|
||||
{
|
||||
case "RegionName":
|
||||
region.Name = reader.Value;
|
||||
break;
|
||||
case "Point1X":
|
||||
int.TryParse(reader.Value, out rect.X);
|
||||
break;
|
||||
case "Point1Y":
|
||||
int.TryParse(reader.Value, out rect.Y);
|
||||
break;
|
||||
case "Point2X":
|
||||
int.TryParse(reader.Value, out rect.Width);
|
||||
break;
|
||||
case "Point2Y":
|
||||
int.TryParse(reader.Value, out rect.Height);
|
||||
break;
|
||||
case "Protected":
|
||||
region.DisableBuild = reader.Value.ToLower().Equals("true");
|
||||
break;
|
||||
case "WorldName":
|
||||
region.WorldID = reader.Value;
|
||||
break;
|
||||
case "AllowedUserCount":
|
||||
break;
|
||||
case "IP":
|
||||
region.AllowedIDs.Add(int.Parse(reader.Value));
|
||||
break;
|
||||
default:
|
||||
endregion = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
region.Area = rect;
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
string query = (TShock.Config.StorageType.ToLower() == "sqlite") ?
|
||||
"INSERT OR IGNORE INTO Regions VALUES (@0, @1, @2, @3, @4, @5, @6, @7);" :
|
||||
"INSERT IGNORE INTO Regions SET X1=@0, Y1=@1, height=@2, width=@3, RegionName=@4, WorldID=@5, UserIds=@6, Protected=@7;";
|
||||
database.Query(query, region.Area.X, region.Area.Y, region.Area.Width, region.Area.Height, region.Name, region.WorldID, "", region.DisableBuild);
|
||||
|
||||
//Todo: What should this be? We don't really have a way to go from ips to userids
|
||||
/*string.Join(",", region.AllowedIDs)*/
|
||||
}
|
||||
}
|
||||
reader.Close();
|
||||
reader = null;
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "regions.xml");
|
||||
if (!Directory.Exists(path))
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
//File.Move(file, file2);
|
||||
}
|
||||
if (updates > 0)
|
||||
ReloadAllRegions();
|
||||
}
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "regions.xml");
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
|
||||
ReloadAllRegions();
|
||||
}
|
||||
|
||||
public void ConvertDB()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE Regions SET WorldID=@worldid";
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
com.CommandText = "UPDATE Regions SET UserIds=@UserIds";
|
||||
com.AddParameter("@UserIds", "");
|
||||
com.ExecuteNonQuery();
|
||||
ReloadAllRegions();
|
||||
}
|
||||
database.Query("UPDATE Regions SET WorldID=@0, UserIds=''", Main.worldID.ToString());
|
||||
ReloadAllRegions();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -232,50 +161,45 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", Main.worldID.ToString()))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Regions WHERE WorldID=@worldid";
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
using (var reader = com.ExecuteReader())
|
||||
Regions.Clear();
|
||||
while (reader.Read())
|
||||
{
|
||||
Regions.Clear();
|
||||
while (reader.Read())
|
||||
int X1 = reader.Get<int>("X1");
|
||||
int Y1 = reader.Get<int>("Y1");
|
||||
int height = reader.Get<int>("height");
|
||||
int width = reader.Get<int>("width");
|
||||
int Protected = reader.Get<int>("Protected");
|
||||
string MergedIDs = reader.Get<string>("UserIds");
|
||||
string name = reader.Get<string>("RegionName");
|
||||
|
||||
string[] SplitIDs = MergedIDs.Split(',');
|
||||
|
||||
Region r = new Region(new Rectangle(X1, Y1, width, height), name, Protected != 0, Main.worldID.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
int X1 = reader.Get<int>("X1");
|
||||
int Y1 = reader.Get<int>("Y1");
|
||||
int height = reader.Get<int>("height");
|
||||
int width = reader.Get<int>("width");
|
||||
int Protected = reader.Get<int>("Protected");
|
||||
string MergedIDs = DbExt.Get<string>(reader, "UserIds");
|
||||
string name = DbExt.Get<string>(reader, "RegionName");
|
||||
System.Console.WriteLine(MergedIDs);
|
||||
string[] SplitIDs = MergedIDs.Split(',');
|
||||
|
||||
Region r = new Region(new Rectangle(X1, Y1, width, height), name, Protected, Main.worldID.ToString());
|
||||
r.RegionAllowedIDs = new int[SplitIDs.Length];
|
||||
try
|
||||
for (int i = 0; i < SplitIDs.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < SplitIDs.Length; i++)
|
||||
{
|
||||
if (SplitIDs.Length == 1 && SplitIDs[0].Equals(""))
|
||||
{
|
||||
break;
|
||||
}
|
||||
//System.Console.WriteLine(SplitIDs[i]);
|
||||
r.RegionAllowedIDs[i] = Convert.ToInt32(SplitIDs[i]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error("Your database contains invalid UserIDs (they should be ints).");
|
||||
Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
|
||||
Log.Error(e.Message);
|
||||
Log.Error(e.StackTrace);
|
||||
}
|
||||
int id;
|
||||
|
||||
Regions.Add(r);
|
||||
if (Int32.TryParse(SplitIDs[i], out id)) // if unparsable, it's not an int, so silently skip
|
||||
r.AllowedIDs.Add(id);
|
||||
else if (SplitIDs[i] == "") // Split gotcha, can return an empty string with certain conditions
|
||||
// but we only want to let the user know if it's really a nonparsable integer.
|
||||
Log.Warn("One of your UserIDs is not a usable integer: " + SplitIDs[i]);
|
||||
}
|
||||
}
|
||||
reader.Close();
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error("Your database contains invalid UserIDs (they should be ints).");
|
||||
Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
|
||||
Log.Error(e.Message);
|
||||
Log.Error(e.StackTrace);
|
||||
}
|
||||
|
||||
Regions.Add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -285,29 +209,58 @@ namespace TShockAPI.DB
|
|||
}
|
||||
}
|
||||
|
||||
public void ReloadForUnitTest(String n)
|
||||
{
|
||||
|
||||
using (var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", n))
|
||||
{
|
||||
Regions.Clear();
|
||||
while (reader.Read())
|
||||
{
|
||||
int X1 = reader.Get<int>("X1");
|
||||
int Y1 = reader.Get<int>("Y1");
|
||||
int height = reader.Get<int>("height");
|
||||
int width = reader.Get<int>("width");
|
||||
int Protected = reader.Get<int>("Protected");
|
||||
string MergedIDs = reader.Get<string>("UserIds");
|
||||
string name = reader.Get<string>("RegionName");
|
||||
string[] SplitIDs = MergedIDs.Split(',');
|
||||
|
||||
Region r = new Region(new Rectangle(X1, Y1, width, height), name, Protected != 0, Main.worldID.ToString());
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < SplitIDs.Length; i++)
|
||||
{
|
||||
int id;
|
||||
|
||||
if (Int32.TryParse(SplitIDs[i], out id)) // if unparsable, it's not an int, so silently skip
|
||||
r.AllowedIDs.Add(id);
|
||||
else if (SplitIDs[i] == "") // Split gotcha, can return an empty string with certain conditions
|
||||
// but we only want to let the user know if it's really a nonparsable integer.
|
||||
Log.Warn("UnitTest: One of your UserIDs is not a usable integer: " + SplitIDs[i]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error("Your database contains invalid UserIDs (they should be ints).");
|
||||
Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
|
||||
Log.Error(e.Message);
|
||||
Log.Error(e.StackTrace);
|
||||
}
|
||||
|
||||
Regions.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool AddRegion(int tx, int ty, int width, int height, string regionname, string worldid)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"INSERT INTO Regions VALUES (@tx, @ty, @height, @width, @name, @worldid, @userids, @protected);";
|
||||
com.AddParameter("@tx", tx);
|
||||
com.AddParameter("@ty", ty);
|
||||
com.AddParameter("@width", width);
|
||||
com.AddParameter("@height", height);
|
||||
com.AddParameter("@name", regionname.ToLower());
|
||||
com.AddParameter("@worldid", worldid);
|
||||
com.AddParameter("@userids", "");
|
||||
com.AddParameter("@protected", 1);
|
||||
if (com.ExecuteNonQuery() > 0)
|
||||
{
|
||||
Regions.Add(new Region(new Rectangle(tx, ty, width, height), regionname, 0, worldid));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
database.Query("INSERT INTO Regions VALUES (@0, @1, @2, @3, @4, @5, @6, @7);", tx, ty, width, height, regionname, worldid, "", 1);
|
||||
Regions.Add(new Region(new Rectangle(tx, ty, width, height), regionname, true, worldid));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -320,15 +273,9 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "DELETE FROM Regions WHERE RegionName=@name AND WorldID=@worldid";
|
||||
com.AddParameter("@name", name.ToLower());
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
ReloadAllRegions();
|
||||
return true;
|
||||
}
|
||||
database.Query("DELETE FROM Regions WHERE RegionName=@0 AND WorldID=@1", name, Main.worldID.ToString());
|
||||
Regions.Remove(getRegion(name));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -341,16 +288,24 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE Regions SET Protected=@bool WHERE RegionName=@name AND WorldID=@worldid";
|
||||
com.AddParameter("@name", name);
|
||||
com.AddParameter("@bool", state ? 1 : 0);
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
int q = com.ExecuteNonQuery();
|
||||
ReloadAllRegions();
|
||||
return (q > 0);
|
||||
}
|
||||
database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, Main.worldID.ToString());
|
||||
getRegion(name).DisableBuild = state;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SetRegionStateTest(string name, string world, bool state)
|
||||
{
|
||||
try
|
||||
{
|
||||
database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, world);
|
||||
getRegion(name).DisableBuild = state;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -379,9 +334,9 @@ namespace TShockAPI.DB
|
|||
{
|
||||
foreach (Region region in Regions)
|
||||
{
|
||||
if (x >= region.RegionArea.Left && x <= region.RegionArea.Right &&
|
||||
y >= region.RegionArea.Top && y <= region.RegionArea.Bottom &&
|
||||
region.DisableBuild == 1)
|
||||
if (x >= region.Area.Left && x <= region.Area.Right &&
|
||||
y >= region.Area.Top && y <= region.Area.Bottom &&
|
||||
region.DisableBuild)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -392,7 +347,7 @@ namespace TShockAPI.DB
|
|||
public static List<string> ListIDs(string MergedIDs)
|
||||
{
|
||||
List<string> SplitIDs = new List<string>();
|
||||
var sb = new StringBuilder();
|
||||
/*var sb = new StringBuilder();
|
||||
for (int i = 0; i < MergedIDs.Length; i++)
|
||||
{
|
||||
char c = MergedIDs[i];
|
||||
|
|
@ -406,53 +361,43 @@ namespace TShockAPI.DB
|
|||
SplitIDs.Add(sb.ToString());
|
||||
sb.Clear();
|
||||
}
|
||||
}*/
|
||||
String[] s = MergedIDs.Split(',');
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
if (!s[i].Equals(""))
|
||||
SplitIDs.Add(s[i]);
|
||||
}
|
||||
return SplitIDs;
|
||||
}
|
||||
|
||||
public bool AddNewUser(string regionName, String userName)
|
||||
{
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
string MergedIDs = string.Empty;
|
||||
using (var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName, Main.worldID.ToString()))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Regions WHERE RegionName=@name AND WorldID=@worldid";
|
||||
com.AddParameter("@name", regionName);
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
string MergedIDs = string.Empty;
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
MergedIDs = reader.Get<string>("UserIds");
|
||||
}
|
||||
if (reader.Read())
|
||||
MergedIDs = reader.Get<string>("UserIds");
|
||||
}
|
||||
|
||||
if (MergedIDs == string.Empty)
|
||||
MergedIDs = Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
else
|
||||
MergedIDs = MergedIDs + "," + Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
com.Parameters.Clear();
|
||||
com.CommandText = "UPDATE Regions SET UserIds=@ids WHERE RegionName=@name AND WorldID=@worldid";
|
||||
com.AddParameter("@ids", MergedIDs);
|
||||
com.AddParameter("@name", regionName);
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
if (com.ExecuteNonQuery() > 0)
|
||||
{
|
||||
ReloadAllRegions();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (MergedIDs == string.Empty)
|
||||
MergedIDs = Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
else
|
||||
MergedIDs = MergedIDs + "," + Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
|
||||
if (database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", MergedIDs, regionName, Main.worldID.ToString()) > 0)
|
||||
{
|
||||
ReloadAllRegions();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -465,15 +410,10 @@ namespace TShockAPI.DB
|
|||
var regions = new List<Region>();
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT RegionName FROM Regions WHERE WorldID=@0", worldid))
|
||||
{
|
||||
com.CommandText = "SELECT RegionName FROM Regions WHERE WorldID=@worldid";
|
||||
com.AddParameter("@worldid", worldid);
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
regions.Add(new Region { RegionName = reader.Get<string>("RegionName") });
|
||||
}
|
||||
while (reader.Read())
|
||||
regions.Add(new Region { Name = reader.Get<string>("RegionName") });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -482,35 +422,47 @@ namespace TShockAPI.DB
|
|||
}
|
||||
return regions;
|
||||
}
|
||||
|
||||
public Region getRegion(String name)
|
||||
{
|
||||
foreach (Region r in Regions)
|
||||
{
|
||||
if (r.Name.Equals(name))
|
||||
return r;
|
||||
}
|
||||
return new Region();
|
||||
}
|
||||
}
|
||||
|
||||
public class Region
|
||||
{
|
||||
public Rectangle RegionArea { get; set; }
|
||||
public string RegionName { get; set; }
|
||||
public int DisableBuild { get; set; }
|
||||
public string RegionWorldID { get; set; }
|
||||
public int[] RegionAllowedIDs { get; set; }
|
||||
public Rectangle Area { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool DisableBuild { get; set; }
|
||||
public string WorldID { get; set; }
|
||||
public List<int> AllowedIDs { get; set; }
|
||||
|
||||
public Region(Rectangle region, string name, int disablebuild, string RegionWorldIDz)
|
||||
public Region(Rectangle region, string name, bool disablebuild, string RegionWorldIDz)
|
||||
: this()
|
||||
{
|
||||
RegionArea = region;
|
||||
RegionName = name;
|
||||
Area = region;
|
||||
Name = name;
|
||||
DisableBuild = disablebuild;
|
||||
RegionWorldID = RegionWorldIDz;
|
||||
WorldID = RegionWorldIDz;
|
||||
}
|
||||
|
||||
public Region()
|
||||
{
|
||||
RegionArea = Rectangle.Empty;
|
||||
RegionName = string.Empty;
|
||||
DisableBuild = 1;
|
||||
RegionWorldID = string.Empty;
|
||||
Area = Rectangle.Empty;
|
||||
Name = string.Empty;
|
||||
DisableBuild = true;
|
||||
WorldID = string.Empty;
|
||||
AllowedIDs = new List<int>();
|
||||
}
|
||||
|
||||
public bool InArea(Rectangle point)
|
||||
{
|
||||
if (RegionArea.Contains(point.X, point.Y))
|
||||
if (Area.Contains(point.X, point.Y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -528,14 +480,14 @@ namespace TShockAPI.DB
|
|||
}
|
||||
return false;
|
||||
}
|
||||
if (DisableBuild == 0)
|
||||
if (!DisableBuild)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < RegionAllowedIDs.Length; i++)
|
||||
for (int i = 0; i < AllowedIDs.Count; i++)
|
||||
{
|
||||
if (RegionAllowedIDs[i] == ply.UserID)
|
||||
if (AllowedIDs[i] == ply.UserID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
94
TShockAPI/DB/RememberPosManager.cs
Normal file
94
TShockAPI/DB/RememberPosManager.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
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.Xml;
|
||||
using System.Data;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class RemeberedPosManager
|
||||
{
|
||||
public IDbConnection database;
|
||||
|
||||
public RemeberedPosManager(IDbConnection db)
|
||||
{
|
||||
database = db;
|
||||
|
||||
var table = new SqlTable("RememberedPos",
|
||||
new SqlColumn("Name", MySqlDbType.VarChar, 50) { Primary = true },
|
||||
new SqlColumn("IP", MySqlDbType.Text),
|
||||
new SqlColumn("X", MySqlDbType.Int32),
|
||||
new SqlColumn("Y", MySqlDbType.Int32),
|
||||
new SqlColumn("WorldID", MySqlDbType.Text)
|
||||
);
|
||||
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
}
|
||||
|
||||
public Vector2 GetLeavePos(string name, string IP)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var reader = database.QueryReader("SELECT * FROM RememberedPos WHERE Name=@0 AND IP=@1", name, IP))
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return new Vector2(reader.Get<int>("X"), reader.Get<int>("Y"));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
|
||||
return new Vector2();
|
||||
}
|
||||
|
||||
public void InsertLeavePos(string name, string IP, int X, int Y)
|
||||
{
|
||||
if (GetLeavePos(name, IP) == Vector2.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
database.Query("INSERT INTO RememberedPos (Name, IP, X, Y, WorldID) VALUES (@0, @1, @2, @3, @4);", name, IP, X, Y + 3, Main.worldID.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
database.Query("UPDATE RememberedPos SET X = @0, Y = @1 WHERE Name = @2 AND IP = @3 AND WorldID = @4;", X, Y + 3, name, IP, Main.worldID.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
TShockAPI/DB/SqlColumn.cs
Normal file
35
TShockAPI/DB/SqlColumn.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class SqlColumn
|
||||
{
|
||||
//Required
|
||||
public string Name { get; set; }
|
||||
public MySqlDbType Type { get; set; }
|
||||
|
||||
|
||||
//Optional
|
||||
public bool Unique { get; set; }
|
||||
public bool Primary { get; set; }
|
||||
public bool AutoIncrement { get; set; }
|
||||
public bool NotNull { get; set; }
|
||||
public string DefaultValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Length of the data type, null = default
|
||||
/// </summary>
|
||||
public int? Length { get; set; }
|
||||
|
||||
public SqlColumn(string name, MySqlDbType type)
|
||||
: this(name, type, null)
|
||||
{
|
||||
}
|
||||
public SqlColumn(string name, MySqlDbType type, int? length)
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
Length = length;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
TShockAPI/DB/SqlTable.cs
Normal file
80
TShockAPI/DB/SqlTable.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class SqlTable
|
||||
{
|
||||
public List<SqlColumn> Columns { get; protected set; }
|
||||
public string Name { get; protected set; }
|
||||
public SqlTable(string name, params SqlColumn[] columns)
|
||||
: this(name, new List<SqlColumn>(columns))
|
||||
{
|
||||
}
|
||||
public SqlTable(string name, List<SqlColumn> columns)
|
||||
{
|
||||
Name = name;
|
||||
Columns = columns;
|
||||
}
|
||||
}
|
||||
|
||||
public class SqlTableCreator
|
||||
{
|
||||
IDbConnection database;
|
||||
IQueryBuilder creator;
|
||||
public SqlTableCreator(IDbConnection db, IQueryBuilder provider)
|
||||
{
|
||||
database = db;
|
||||
creator = provider;
|
||||
}
|
||||
|
||||
public void EnsureExists(SqlTable table)
|
||||
{
|
||||
var columns = GetColumns(table);
|
||||
if (columns.Count > 0)
|
||||
{
|
||||
if (!table.Columns.All(c => columns.Contains(c.Name)) || !columns.All(c => table.Columns.Any(c2 => c2.Name == c)))
|
||||
{
|
||||
var from = new SqlTable(table.Name, columns.Select(s => new SqlColumn(s, MySqlDbType.String)).ToList());
|
||||
database.Query(creator.AlterTable(from, table));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
database.Query(creator.CreateTable(table));
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> GetColumns(SqlTable table)
|
||||
{
|
||||
var ret = new List<string>();
|
||||
var name = database.GetSqlType();
|
||||
if (name == SqlType.Sqlite)
|
||||
{
|
||||
using (var reader = database.QueryReader("PRAGMA table_info({0})".SFormat(table.Name)))
|
||||
{
|
||||
while (reader.Read())
|
||||
ret.Add(reader.Get<string>("name"));
|
||||
}
|
||||
}
|
||||
else if (name == SqlType.Mysql)
|
||||
{
|
||||
using (var reader = database.QueryReader("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME=@0 AND TABLE_SCHEMA=@1", table.Name, database.Database))
|
||||
{
|
||||
while (reader.Read())
|
||||
ret.Add(reader.Get<string>("COLUMN_NAME"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
TShockAPI/DB/SqlValue.cs
Normal file
53
TShockAPI/DB/SqlValue.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
using System.Data;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class SqlValue
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public object Value { get; set; }
|
||||
|
||||
public SqlValue(string name, object value)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public class SqlTableEditor
|
||||
{
|
||||
IDbConnection database;
|
||||
IQueryBuilder creator;
|
||||
|
||||
public SqlTableEditor(IDbConnection db, IQueryBuilder provider)
|
||||
{
|
||||
database = db;
|
||||
creator = provider;
|
||||
}
|
||||
|
||||
public void UpdateValues(string table, List<SqlValue> values, List<SqlValue> wheres)
|
||||
{
|
||||
database.Query(creator.UpdateValue(table, values, wheres));
|
||||
}
|
||||
|
||||
public void InsertValues(string table, List<SqlValue> values)
|
||||
{
|
||||
database.Query(creator.InsertValues(table, values));
|
||||
}
|
||||
|
||||
public List<object> ReadColumn(string table, string column, List<SqlValue> wheres)
|
||||
{
|
||||
List<object> values = new List<object>();
|
||||
|
||||
using (var reader = database.QueryReader(creator.ReadColumn(table, wheres)))
|
||||
{
|
||||
while (reader.Read())
|
||||
values.Add(reader.Reader.Get<object>(column));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,12 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Community.CsharpSqlite.SQLiteClient;
|
||||
using System.IO;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class UserManager
|
||||
|
|
@ -34,69 +32,63 @@ namespace TShockAPI.DB
|
|||
{
|
||||
database = db;
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
var table = new SqlTable("Users",
|
||||
new SqlColumn("ID", MySqlDbType.Int32) { Primary = true, AutoIncrement = true },
|
||||
new SqlColumn("Username", MySqlDbType.VarChar, 32) { Unique = true },
|
||||
new SqlColumn("Password", MySqlDbType.VarChar, 64),
|
||||
new SqlColumn("Usergroup", MySqlDbType.Text),
|
||||
new SqlColumn("IP", MySqlDbType.VarChar, 32)
|
||||
);
|
||||
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "users.txt");
|
||||
if (File.Exists(file))
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS 'Users' ('ID' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, 'Username' VARCHAR(32) UNIQUE, 'Password' VARCHAR(64), 'Usergroup' TEXT, 'IP' VARCHAR(32));";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS Users (ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Username VARCHAR(32) UNIQUE, Password VARCHAR(64), Usergroup VARCHAR(255), IP VARCHAR(15));";
|
||||
|
||||
com.ExecuteNonQuery();
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "users.txt");
|
||||
if (File.Exists(file))
|
||||
using (StreamReader sr = new StreamReader(file))
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(file))
|
||||
String line;
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
String line;
|
||||
while ((line = sr.ReadLine()) != null )
|
||||
if (line.Equals("") || line.Substring(0, 1).Equals("#"))
|
||||
continue;
|
||||
String[] info = line.Split(' ');
|
||||
String username = "";
|
||||
String sha = "";
|
||||
String group = "";
|
||||
String ip = "";
|
||||
|
||||
String[] nameSha = info[0].Split(':');
|
||||
|
||||
if (nameSha.Length < 2)
|
||||
{
|
||||
if (line.Equals("") || line.Substring(0, 1).Equals("#") )
|
||||
continue;
|
||||
String[] info = line.Split(' ');
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO Users (Username, Password, Usergroup, IP) VALUES (@name, @pass, @group, @ip);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO Users SET Username=@name, Password=@pass, Usergroup=@group, IP=@ip ;";
|
||||
|
||||
String username = "";
|
||||
String sha = "";
|
||||
String group = "";
|
||||
String ip = "";
|
||||
|
||||
String[] nameSha = info[0].Split(':');
|
||||
|
||||
if (nameSha.Length < 2)
|
||||
{
|
||||
username = nameSha[0];
|
||||
ip = nameSha[0];
|
||||
group = info[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
username = nameSha[0];
|
||||
sha = nameSha[1];
|
||||
group = info[1];
|
||||
}
|
||||
com.AddParameter("@name", username.Trim());
|
||||
com.AddParameter("@pass", sha.Trim());
|
||||
com.AddParameter("@group", group.Trim());
|
||||
com.AddParameter("@ip", ip.Trim());
|
||||
com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
username = nameSha[0];
|
||||
ip = nameSha[0];
|
||||
group = info[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
username = nameSha[0];
|
||||
sha = nameSha[1];
|
||||
group = info[1];
|
||||
}
|
||||
|
||||
string query = (TShock.Config.StorageType.ToLower() == "sqlite") ?
|
||||
"INSERT OR IGNORE INTO Users (Username, Password, Usergroup, IP) VALUES (@0, @1, @2, @3)" :
|
||||
"INSERT IGNORE INTO Users SET Username=@0, Password=@1, Usergroup=@2, IP=@3";
|
||||
|
||||
database.Query(query, username.Trim(), sha.Trim(), group.Trim(), ip.Trim());
|
||||
}
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "users.txt");
|
||||
if (!Directory.Exists(path))
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
}
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "users.txt");
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
File.Move(file, file2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -107,24 +99,11 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@name, @password, @group, @ip);";
|
||||
com.AddParameter("@name", user.Name);
|
||||
com.AddParameter("@password", Tools.HashPassword(user.Password));
|
||||
if (!TShock.Groups.GroupExists(user.Group))
|
||||
throw new GroupNotExistsException(user.Group);
|
||||
|
||||
if (!TShock.Groups.GroupExists(user.Group))
|
||||
throw new GroupNotExistsException(user.Group);
|
||||
|
||||
com.AddParameter("@group", user.Group);
|
||||
com.AddParameter("@ip", user.Address);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.RecordsAffected < 1)
|
||||
throw new UserExistsException(user.Name);
|
||||
}
|
||||
}
|
||||
if (database.Query("INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@0, @1, @2, @3);", user.Name, Tools.HashPassword(user.Password), user.Group, user.Address) < 1)
|
||||
throw new UserExistsException(user.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -140,25 +119,18 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
int affected = -1;
|
||||
if (!string.IsNullOrEmpty(user.Address))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(user.Address))
|
||||
{
|
||||
com.CommandText = "DELETE FROM Users WHERE IP=@ip";
|
||||
com.AddParameter("@ip", user.Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
com.CommandText = "DELETE FROM Users WHERE Username=@name";
|
||||
com.AddParameter("@name", user.Name);
|
||||
}
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.RecordsAffected < 1)
|
||||
throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address);
|
||||
}
|
||||
affected = database.Query("DELETE FROM Users WHERE IP=@0", user.Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
affected = database.Query("DELETE FROM Users WHERE Username=@0", user.Name);
|
||||
}
|
||||
|
||||
if (affected < 1)
|
||||
throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -176,18 +148,8 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE Users SET Password = @password WHERE Username = @name;";
|
||||
com.AddParameter("@name", user.Name);
|
||||
com.AddParameter("@password", Tools.HashPassword(password));
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.RecordsAffected < 1)
|
||||
throw new UserExistsException(user.Name);
|
||||
}
|
||||
}
|
||||
if (database.Query("UPDATE Users SET Password = @0 WHERE Username = @1;", Tools.HashPassword(password), user.Name) == 0)
|
||||
throw new UserNotExistException(user.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -204,22 +166,11 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE Users SET UserGroup = @group WHERE Username = @name;";
|
||||
com.AddParameter("@name", user.Name);
|
||||
if (!TShock.Groups.GroupExists(group))
|
||||
throw new GroupNotExistsException(group);
|
||||
|
||||
if (!TShock.Groups.GroupExists(group))
|
||||
throw new GroupNotExistsException(group);
|
||||
|
||||
com.AddParameter("@group", group);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.RecordsAffected < 1)
|
||||
throw new UserExistsException(user.Name);
|
||||
}
|
||||
}
|
||||
if (database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", group, user.Name) == 0)
|
||||
throw new UserNotExistException(user.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -238,26 +189,19 @@ namespace TShockAPI.DB
|
|||
string[] returndata = new string[2];
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Users WHERE Username=@0", username))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Users WHERE Username=@name";
|
||||
com.AddParameter("@name", username.ToLower());
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
if (reader.Read())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
returndata[0] = reader.Get<string>("Password");
|
||||
returndata[1] = reader.Get<string>("UserGroup");
|
||||
return returndata;
|
||||
}
|
||||
reader.Close();
|
||||
returndata[0] = reader.Get<string>("Password");
|
||||
returndata[1] = reader.Get<string>("UserGroup");
|
||||
return returndata;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex.ToString());
|
||||
Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex);
|
||||
}
|
||||
return returndata;
|
||||
}
|
||||
|
|
@ -266,24 +210,17 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Users WHERE Username=@0", username))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Users WHERE Username=@name";
|
||||
com.AddParameter("@name", username.ToLower());
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
if (reader.Read())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return reader.Get<int>("ID");
|
||||
}
|
||||
reader.Close();
|
||||
return reader.Get<int>("ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex.ToString());
|
||||
Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -296,24 +233,18 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Users WHERE IP=@0", ip))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Users WHERE IP=@ip";
|
||||
com.AddParameter("@ip", ip);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
if (reader.Read())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
string group = reader.Get<string>("UserGroup");
|
||||
return Tools.GetGroup(group);
|
||||
}
|
||||
string group = reader.Get<string>("UserGroup");
|
||||
return Tools.GetGroup(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex.ToString());
|
||||
Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex);
|
||||
}
|
||||
return Tools.GetGroup("default");
|
||||
}
|
||||
|
|
@ -322,26 +253,20 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT IP, UserGroup FROM Users"))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Users";
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
while(reader.Read())
|
||||
if (Tools.GetIPv4Address(reader.Get<string>("IP")) == ip)
|
||||
{
|
||||
if (Tools.GetIPv4Address(reader.Get<string>("IP")) == ip)
|
||||
{
|
||||
string group = reader.Get<string>("UserGroup");
|
||||
return Tools.GetGroup(group);
|
||||
}
|
||||
return Tools.GetGroup(reader.Get<string>("UserGroup"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex.ToString());
|
||||
Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex);
|
||||
}
|
||||
return Tools.GetGroup("default");
|
||||
}
|
||||
|
|
@ -373,27 +298,23 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
QueryResult result;
|
||||
if (string.IsNullOrEmpty(user.Address))
|
||||
{
|
||||
if (string.IsNullOrEmpty(user.Address))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Users WHERE Username=@name";
|
||||
com.AddParameter("@name", user.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Users WHERE IP=@ip";
|
||||
com.AddParameter("@ip", user.Address);
|
||||
}
|
||||
result = database.QueryReader("SELECT * FROM Users WHERE Username=@0", user.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = database.QueryReader("SELECT * FROM Users WHERE IP=@0", user.Address);
|
||||
}
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
using (var reader = result)
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
user.ID = reader.Get<int>("ID");
|
||||
user.Group = reader.Get<string>("Usergroup");
|
||||
return user;
|
||||
}
|
||||
user.ID = reader.Get<int>("ID");
|
||||
user.Group = reader.Get<string>("Usergroup");
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Xml;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
|
|
@ -34,112 +35,100 @@ namespace TShockAPI.DB
|
|||
{
|
||||
database = db;
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
var table = new SqlTable("Warps",
|
||||
new SqlColumn("WarpName", MySqlDbType.VarChar, 50) { Primary = true},
|
||||
new SqlColumn("X", MySqlDbType.Int32),
|
||||
new SqlColumn("Y", MySqlDbType.Int32),
|
||||
new SqlColumn("WorldID", MySqlDbType.Text),
|
||||
new SqlColumn("Private", MySqlDbType.Text)
|
||||
);
|
||||
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "warps.xml");
|
||||
String name = "";
|
||||
String world = "";
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
if (File.Exists(file))
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS 'Warps' ('X' NUMERIC, 'Y' NUMERIC, 'WarpName' TEXT PRIMARY KEY, 'WorldID' TEXT);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText =
|
||||
"CREATE TABLE IF NOT EXISTS Warps (X INT(11), Y INT(11), WarpName VARCHAR(255) PRIMARY, WorldID VARCHAR(255));";
|
||||
|
||||
com.ExecuteNonQuery();
|
||||
|
||||
String file = Path.Combine(TShock.SavePath, "warps.xml");
|
||||
String name = "";
|
||||
String world = "";
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
if (File.Exists(file))
|
||||
XmlReader reader;
|
||||
using (reader = XmlReader.Create(new StreamReader(file)))
|
||||
{
|
||||
XmlReader reader;
|
||||
using (reader = XmlReader.Create(new StreamReader(file)))
|
||||
// Parse the file and display each of the nodes.
|
||||
while (reader.Read())
|
||||
{
|
||||
// Parse the file and display each of the nodes.
|
||||
while (reader.Read())
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
case XmlNodeType.Element:
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "Warp":
|
||||
name = "";
|
||||
world = "";
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
break;
|
||||
case "WarpName":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
name = reader.Value;
|
||||
break;
|
||||
case "X":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out x1);
|
||||
break;
|
||||
case "Y":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out y1);
|
||||
break;
|
||||
case "WorldName":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
world = reader.Value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.Text:
|
||||
case XmlNodeType.Element:
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "Warp":
|
||||
name = "";
|
||||
world = "";
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
break;
|
||||
case "WarpName":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
name = reader.Value;
|
||||
break;
|
||||
case "X":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out x1);
|
||||
break;
|
||||
case "Y":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
int.TryParse(reader.Value, out y1);
|
||||
break;
|
||||
case "WorldName":
|
||||
while (reader.NodeType != XmlNodeType.Text)
|
||||
reader.Read();
|
||||
world = reader.Value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.Text:
|
||||
|
||||
break;
|
||||
case XmlNodeType.XmlDeclaration:
|
||||
case XmlNodeType.ProcessingInstruction:
|
||||
break;
|
||||
case XmlNodeType.Comment:
|
||||
break;
|
||||
case XmlNodeType.EndElement:
|
||||
if (reader.Name.Equals("Warp"))
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO Warps VALUES (@tx, @ty,@name, @worldid);";
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO Warps SET X=@tx, Y=@ty, WarpName=@name, WorldID=@worldid;";
|
||||
com.AddParameter("@tx", x1);
|
||||
com.AddParameter("@ty", y1);
|
||||
com.AddParameter("@name", name);
|
||||
com.AddParameter("@worldid", world);
|
||||
com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.XmlDeclaration:
|
||||
case XmlNodeType.ProcessingInstruction:
|
||||
break;
|
||||
case XmlNodeType.Comment:
|
||||
break;
|
||||
case XmlNodeType.EndElement:
|
||||
if (reader.Name.Equals("Warp"))
|
||||
{
|
||||
string query = (TShock.Config.StorageType.ToLower() == "sqlite") ?
|
||||
"INSERT OR IGNORE INTO Warps VALUES (@0, @1,@2, @3);" :
|
||||
"INSERT IGNORE INTO Warps SET X=@0, Y=@1, WarpName=@2, WorldID=@3;";
|
||||
database.Query(query, x1, y1, name, world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
reader.Close();
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "warps.xml");
|
||||
if (!Directory.Exists(path))
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
//File.Move(file, file2);
|
||||
|
||||
}
|
||||
reader.Close();
|
||||
String path = Path.Combine(TShock.SavePath, "old_configs");
|
||||
String file2 = Path.Combine(path, "warps.xml");
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
if (File.Exists(file2))
|
||||
File.Delete(file2);
|
||||
//File.Move(file, file2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void ConvertDB()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE Warps SET WorldID=@worldid";
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
database.Query("UPDATE Warps SET WorldID=@0", Main.worldID.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -151,16 +140,8 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "INSERT INTO Warps (X, Y, WarpName, WorldID) VALUES (@x, @y, @name, @worldid);";
|
||||
com.AddParameter("@x", x);
|
||||
com.AddParameter("@y", y);
|
||||
com.AddParameter("@name", name.ToLower());
|
||||
com.AddParameter("@worldid", worldid);
|
||||
com.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
database.Query("INSERT INTO Warps (X, Y, WarpName, WorldID) VALUES (@0, @1, @2, @3);", x, y, name, worldid);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -173,14 +154,8 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
com.CommandText = "DELETE FROM Warps WHERE WarpName=@name AND WorldID=@worldid";
|
||||
com.AddParameter("@name", name.ToLower());
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
database.Query("DELETE FROM Warps WHERE WarpName=@0 AND WorldID=@1", name, Main.worldID.ToString());
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -193,18 +168,18 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Warps WHERE WarpName=@0 AND WorldID=@1", name, Main.worldID.ToString()))
|
||||
{
|
||||
com.CommandText = "SELECT * FROM Warps WHERE WarpName=@name AND WorldID=@worldid";
|
||||
com.AddParameter("@name", name);
|
||||
com.AddParameter("@worldid", Main.worldID.ToString());
|
||||
using (var reader = com.ExecuteReader())
|
||||
if (reader.Read())
|
||||
{
|
||||
if (reader.Read())
|
||||
try
|
||||
{
|
||||
return new Warp(new Vector2(reader.Get<int>("X"), reader.Get<int>("Y")), reader.Get<string>("WarpName"), reader.Get<string>("WorldID"));
|
||||
return new Warp(new Vector2(reader.Get<int>("X"), reader.Get<int>("Y")), reader.Get<string>("WarpName"), reader.Get<string>("WorldID"), reader.Get<string>("Private"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new Warp(new Vector2(reader.Get<int>("X"), reader.Get<int>("Y")), reader.Get<string>("WarpName"), reader.Get<string>("WorldID"), "0");
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -220,19 +195,24 @@ namespace TShockAPI.DB
|
|||
/// </summary>
|
||||
/// <param name="worldid">World name to get warps from</param>
|
||||
/// <returns>List of warps with only their names</returns>
|
||||
public List<Warp> ListAllWarps(string worldid)
|
||||
public List<Warp> ListAllPublicWarps(string worldid)
|
||||
{
|
||||
var warps = new List<Warp>();
|
||||
try
|
||||
{
|
||||
using (var com = database.CreateCommand())
|
||||
using (var reader = database.QueryReader("SELECT * FROM Warps WHERE WorldID=@0", worldid))
|
||||
{
|
||||
com.CommandText = "SELECT WarpName FROM Warps WHERE WorldID=@worldid";
|
||||
com.AddParameter("@worldid", worldid);
|
||||
using (var reader = com.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
while (reader.Read())
|
||||
try
|
||||
{
|
||||
if (reader.Get<String>("Private") == "0" || reader.Get<String>("Private") == null)
|
||||
warps.Add(new Warp { WarpName = reader.Get<string>("WarpName") });
|
||||
}
|
||||
catch
|
||||
{
|
||||
warps.Add(new Warp { WarpName = reader.Get<string>("WarpName") });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -242,6 +222,28 @@ namespace TShockAPI.DB
|
|||
}
|
||||
return warps;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the warps names from world
|
||||
/// </summary>
|
||||
/// <param name="worldid">World name to get warps from</param>
|
||||
/// <returns>List of warps with only their names</returns>
|
||||
public bool HideWarp(string warp, bool state)
|
||||
{
|
||||
try
|
||||
{
|
||||
string query = "UPDATE Warps SET Private=@0 WHERE WarpName=@1 AND WorldID=@2";
|
||||
|
||||
database.Query(query, state ? "1" : "0", warp, Main.worldID.ToString());
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Warp
|
||||
|
|
@ -249,12 +251,14 @@ namespace TShockAPI.DB
|
|||
public Vector2 WarpPos { get; set; }
|
||||
public string WarpName { get; set; }
|
||||
public string WorldWarpID { get; set; }
|
||||
public string Private { get; set; }
|
||||
|
||||
public Warp(Vector2 warppos, string name, string worldname)
|
||||
public Warp(Vector2 warppos, string name, string worldid, string hidden)
|
||||
{
|
||||
WarpPos = warppos;
|
||||
WarpName = name;
|
||||
WorldWarpID = worldname;
|
||||
WorldWarpID = worldid;
|
||||
Private = hidden;
|
||||
}
|
||||
|
||||
public Warp()
|
||||
|
|
@ -262,6 +266,7 @@ namespace TShockAPI.DB
|
|||
WarpPos = Vector2.Zero;
|
||||
WarpName = null;
|
||||
WorldWarpID = string.Empty;
|
||||
Private = "0";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
317
TShockAPI/DBTools.cs
Normal file
317
TShockAPI/DBTools.cs
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TShockAPI.DB;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public class DBTools
|
||||
{
|
||||
internal static IDbConnection database;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Table, within the current open DB
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the Table</param>
|
||||
/// <param name="columns">The list of columns that the Table will have</param>
|
||||
/// <param name="IfNotExists">Only try create Table if it does not exist</param>
|
||||
public static void CreateTable(string name, List<Column> columns, bool IfNotExists =true)
|
||||
{
|
||||
//Build up Creation string :)
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("CREATE TABLE ");
|
||||
|
||||
if (IfNotExists)
|
||||
sb.Append("IF NOT EXISTS ");
|
||||
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
sb.Append("'" + name + "' (");
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
sb.Append(name + " (");
|
||||
|
||||
int count = 0;
|
||||
|
||||
foreach (Column column in columns)
|
||||
{
|
||||
count++;
|
||||
if (column.Type.ToLower() == "int")
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
sb.Append(column.Name + " NUMERIC ");
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
sb.Append(column.Name + " INT(255) ");
|
||||
}
|
||||
else if (column.Type.ToLower() == "string")
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
sb.Append(column.Name + " TEXT ");
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
sb.Append(column.Name + " VARCHAR(255) ");
|
||||
}
|
||||
|
||||
if (column.Unique)
|
||||
sb.Append("UNIQUE");
|
||||
|
||||
if (columns.Count == count)
|
||||
sb.Append(")");
|
||||
else
|
||||
sb.Append(", ");
|
||||
}
|
||||
|
||||
database.Query(sb.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a list of values into a Table, if conditions are met
|
||||
/// </summary>
|
||||
/// <param name="tablename">Name of the Table</param>
|
||||
/// <param name="Ignore">Ignore insert if feild is unique and there is already a exact entry</param>
|
||||
/// <param name="Values">The list of values to enter into the table</param>
|
||||
/// <param name="WhereStatements">The list of where statements that must be met, can be an empty list</param>
|
||||
public static int InsertTable(string tablename, bool Ignore, List<ColumnData> Values, List<ColumnData> WhereStatements)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("INSERT ");
|
||||
|
||||
if (Ignore)
|
||||
{
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
sb.Append("OR IGNORE ");
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
sb.Append("IGNORE ");
|
||||
}
|
||||
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
sb.Append("INTO '" + tablename + "' (");
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
sb.Append("INTO " + tablename + " ");
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
//Values
|
||||
if (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (ColumnData columnname in Values)
|
||||
{
|
||||
count++;
|
||||
if (Values.Count != count)
|
||||
sb.Append(columnname.Name + ", ");
|
||||
else
|
||||
sb.Append(columnname.Name + ") ");
|
||||
}
|
||||
|
||||
sb.Append("VALUES (");
|
||||
count = 0;
|
||||
|
||||
foreach (ColumnData columnname in Values)
|
||||
{
|
||||
count++;
|
||||
if (Values.Count != count)
|
||||
{
|
||||
sb.Append("@" + columnname.Name.ToLower() + ", ");
|
||||
com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("@" + columnname.Name.ToLower() + ") ");
|
||||
com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (TShock.Config.StorageType.ToLower() == "mysql")
|
||||
{
|
||||
sb.Append("SET ");
|
||||
int count = 0;
|
||||
|
||||
foreach (ColumnData columnname in Values)
|
||||
{
|
||||
count++;
|
||||
if (Values.Count != count)
|
||||
{
|
||||
sb.Append("@" + columnname.Name.ToLower() + "=" + columnname.Value + ", ");
|
||||
com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("@" + columnname.Name.ToLower() + "=" + columnname.Value + ") ");
|
||||
com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Where Statement (if any)
|
||||
if (WhereStatements.Count > 0)
|
||||
{
|
||||
sb.Append("WHERE ");
|
||||
int count = 0;
|
||||
|
||||
foreach (ColumnData columnname in WhereStatements)
|
||||
{
|
||||
count++;
|
||||
if (Values.Count != count)
|
||||
{
|
||||
sb.Append("@" + columnname.Name.ToLower() + "-where" + "=" + columnname.Value + " AND ");
|
||||
com.AddParameter("@" + columnname.Name.ToLower() + "-where", columnname.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("@" + columnname.Name.ToLower() + "-where" + "=" + columnname.Value + ";");
|
||||
com.AddParameter("@" + columnname.Name.ToLower() + "-where", columnname.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
com.CommandText = sb.ToString();
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
return reader.RecordsAffected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of values from a given Table, where conditions are met
|
||||
/// </summary>
|
||||
/// <param name="tablename">Name of the Table</param>
|
||||
/// <param name="getcolumn">The name of the column you are getting the values from</param>
|
||||
/// <param name="WhereStatements">The list of where statements that must be met, can be an empty list</param>
|
||||
public static List<object> ReadTable(string tablename, string getcolumn, List<ColumnData> WhereStatements)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<object> ReturnedValues = new List<object>();
|
||||
|
||||
sb.Append("SELECT * FROM " + tablename + " ");
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
//Where Statement (if any)
|
||||
if (WhereStatements.Count > 0)
|
||||
{
|
||||
sb.Append("WHERE ");
|
||||
int count = 0;
|
||||
|
||||
foreach (ColumnData columnname in WhereStatements)
|
||||
{
|
||||
count++;
|
||||
if (WhereStatements.Count != count)
|
||||
{
|
||||
sb.Append(columnname.Name + " =" + columnname.Value + " AND ");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(columnname.Name + " =" + columnname.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
com.CommandText = sb.ToString();
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
ReturnedValues.Add(reader.Get<object>(getcolumn));
|
||||
}
|
||||
}
|
||||
return ReturnedValues;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets values in a Table, where statements are met
|
||||
/// </summary>
|
||||
/// <param name="tablename">Name of the Table</param>
|
||||
/// <param name="setcolumn">The column data you are setting</param>
|
||||
/// <param name="WhereStatements">The list of where statements that must be met, can be an empty list</param>
|
||||
public static int SetTable(string tablename, ColumnData setcolumn, List<ColumnData> WhereStatements)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append("UPDATE " + tablename + " SET " + setcolumn.Name + "=@setcolumn ");
|
||||
|
||||
using (var com = database.CreateCommand())
|
||||
{
|
||||
//Where Statement (if any)
|
||||
if (WhereStatements.Count > 0)
|
||||
{
|
||||
sb.Append("WHERE ");
|
||||
int count = 0;
|
||||
|
||||
foreach (ColumnData columnname in WhereStatements)
|
||||
{
|
||||
count++;
|
||||
if (WhereStatements.Count != count)
|
||||
{
|
||||
sb.Append(columnname.Name + " =" + columnname.Value + " AND ");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(columnname.Name + " =" + columnname.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
com.CommandText = sb.ToString();
|
||||
com.AddParameter("@setcolumn", setcolumn.Value);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
return reader.RecordsAffected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Column
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Type { get; set; }
|
||||
public bool Unique { get; set; }
|
||||
public string Parameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The class for creating a new column type
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the column</param>
|
||||
/// <param name="unique">Whether there can be more than one exact value in the column</param>
|
||||
/// <param name="type">The type of column, currently the api only supports "string" or "int"</param>
|
||||
/// <param name="parameters">Extra SQL parameters given, can cause errors cross different SQL (SQLite and MySql)</param>
|
||||
public Column(string name, bool unique, string type, string parameters = "")
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
Unique = unique;
|
||||
Parameters = parameters;
|
||||
}
|
||||
|
||||
public Column()
|
||||
{
|
||||
Name = string.Empty;
|
||||
Type = string.Empty;
|
||||
Unique = false;
|
||||
Parameters = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public class ColumnData
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public object Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The class for testing, inserting or setting column data
|
||||
/// </summary>
|
||||
/// <param name="name">Column Name</param>
|
||||
/// <param name="value">Column Value</param>
|
||||
public ColumnData(string name, object value)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public ColumnData()
|
||||
{
|
||||
Name = string.Empty;
|
||||
Value = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
141
TShockAPI/Extensions/DbExt.cs
Normal file
141
TShockAPI/Extensions/DbExt.cs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public static class DbExt
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Executes a query on a database.
|
||||
/// </summary>
|
||||
/// <param name="olddb">Database to query</param>
|
||||
/// <param name="query">Query string with parameters as @0, @1, etc.</param>
|
||||
/// <param name="args">Parameters to be put in the query</param>
|
||||
/// <returns>Rows affected by query</returns>
|
||||
public static int Query(this IDbConnection olddb, string query, params object[] args)
|
||||
{
|
||||
using (var db = olddb.CloneEx())
|
||||
{
|
||||
db.Open();
|
||||
using (var com = db.CreateCommand())
|
||||
{
|
||||
com.CommandText = query;
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
com.AddParameter("@" + i, args[i]);
|
||||
|
||||
return com.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Executes a query on a database.
|
||||
/// </summary>
|
||||
/// <param name="olddb">Database to query</param>
|
||||
/// <param name="query">Query string with parameters as @0, @1, etc.</param>
|
||||
/// <param name="args">Parameters to be put in the query</param>
|
||||
/// <returns>Query result as IDataReader</returns>
|
||||
public static QueryResult QueryReader(this IDbConnection olddb, string query, params object[] args)
|
||||
{
|
||||
var db = olddb.CloneEx();
|
||||
db.Open();
|
||||
using (var com = db.CreateCommand())
|
||||
{
|
||||
com.CommandText = query;
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
com.AddParameter("@" + i, args[i]);
|
||||
|
||||
return new QueryResult(db, com.ExecuteReader());
|
||||
}
|
||||
}
|
||||
|
||||
public static IDbDataParameter AddParameter(this IDbCommand command, string name, object data)
|
||||
{
|
||||
var parm = command.CreateParameter();
|
||||
parm.ParameterName = name;
|
||||
parm.Value = data;
|
||||
command.Parameters.Add(parm);
|
||||
return parm;
|
||||
}
|
||||
|
||||
public static IDbConnection CloneEx(this IDbConnection conn)
|
||||
{
|
||||
var clone = (IDbConnection)Activator.CreateInstance(conn.GetType());
|
||||
clone.ConnectionString = conn.ConnectionString;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public static SqlType GetSqlType(this IDbConnection conn)
|
||||
{
|
||||
var name = conn.GetType().Name;
|
||||
if (name == "SqliteConnection")
|
||||
return SqlType.Sqlite;
|
||||
if (name == "MySqlConnection")
|
||||
return SqlType.Mysql;
|
||||
return SqlType.Unknown;
|
||||
}
|
||||
|
||||
static readonly Dictionary<Type, Func<IDataReader, int, object>> ReadFuncs = new Dictionary<Type, Func<IDataReader, int, object>>()
|
||||
{
|
||||
{typeof(bool), (s, i) => s.GetBoolean(i)},
|
||||
{typeof(byte), (s, i) => s.GetByte(i)},
|
||||
{typeof(Int16), (s, i) => s.GetInt16(i)},
|
||||
{typeof(Int32), (s, i) => s.GetInt32(i)},
|
||||
{typeof(Int64), (s, i) => s.GetInt64(i)},
|
||||
{typeof(string), (s, i) => s.GetString(i)},
|
||||
{typeof(decimal), (s, i) => s.GetDecimal(i)},
|
||||
{typeof(float), (s, i) => s.GetFloat(i)},
|
||||
{typeof(double), (s, i) => s.GetDouble(i)},
|
||||
{typeof(object), (s, i) => s.GetValue(i)},
|
||||
};
|
||||
|
||||
public static T Get<T>(this IDataReader reader, string column)
|
||||
{
|
||||
return reader.Get<T>(reader.GetOrdinal(column));
|
||||
}
|
||||
|
||||
public static T Get<T>(this IDataReader reader, int column)
|
||||
{
|
||||
if (ReadFuncs.ContainsKey(typeof(T)))
|
||||
return (T)ReadFuncs[typeof(T)](reader, column);
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public enum SqlType
|
||||
{
|
||||
Unknown,
|
||||
Sqlite,
|
||||
Mysql
|
||||
}
|
||||
|
||||
public class QueryResult : IDisposable
|
||||
{
|
||||
public IDbConnection Connection { get; protected set; }
|
||||
public IDataReader Reader { get; protected set; }
|
||||
|
||||
public QueryResult(IDbConnection conn, IDataReader reader)
|
||||
{
|
||||
Connection = conn;
|
||||
Reader = reader;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Reader.Dispose();
|
||||
Connection.Dispose();
|
||||
}
|
||||
|
||||
public bool Read()
|
||||
{
|
||||
return Reader.Read();
|
||||
}
|
||||
public T Get<T>(string column)
|
||||
{
|
||||
return Reader.Get<T>(Reader.GetOrdinal(column));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
19
TShockAPI/Extensions/LinqExt.cs
Normal file
19
TShockAPI/Extensions/LinqExt.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public static class LinqExt
|
||||
{
|
||||
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException("source");
|
||||
if (action == null) throw new ArgumentNullException("action");
|
||||
|
||||
foreach (T item in source)
|
||||
action(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
TShockAPI/Extensions/RandomExt.cs
Normal file
31
TShockAPI/Extensions/RandomExt.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockAPI.Extensions
|
||||
{
|
||||
public static class RandomExt
|
||||
{
|
||||
public static string NextString(this Random rand, int length)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
switch (rand.Next(0, 3))
|
||||
{
|
||||
case 0:
|
||||
sb.Append((char)rand.Next('a', 'z' + 1));
|
||||
break;
|
||||
case 1:
|
||||
sb.Append((char)rand.Next('A', 'Z' + 1));
|
||||
break;
|
||||
case 2:
|
||||
sb.Append((char)rand.Next('0', '9' + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
TShockAPI/Extensions/StringExt.cs
Normal file
16
TShockAPI/Extensions/StringExt.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public static class StringExt
|
||||
{
|
||||
//Can't name it Format :(
|
||||
public static String SFormat(this String str, params object[] args)
|
||||
{
|
||||
return String.Format(str, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,17 +17,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
internal class FileTools
|
||||
public class FileTools
|
||||
{
|
||||
public static string RulesPath { get { return Path.Combine(TShock.SavePath, "rules.txt"); } }
|
||||
public static string MotdPath { get { return Path.Combine(TShock.SavePath, "motd.txt"); } }
|
||||
public static string WhitelistPath { get { return Path.Combine(TShock.SavePath, "whitelist.txt"); } }
|
||||
public static string RememberedPosPath { get { return Path.Combine(TShock.SavePath, "oldpos.xml"); } }
|
||||
public static string ConfigPath { get { return Path.Combine(TShock.SavePath, "config.json"); } }
|
||||
internal static string RulesPath { get { return Path.Combine(TShock.SavePath, "rules.txt"); } }
|
||||
internal static string MotdPath { get { return Path.Combine(TShock.SavePath, "motd.txt"); } }
|
||||
internal static string WhitelistPath { get { return Path.Combine(TShock.SavePath, "whitelist.txt"); } }
|
||||
internal static string RememberedPosPath { get { return Path.Combine(TShock.SavePath, "oldpos.xml"); } }
|
||||
internal static string ConfigPath { get { return Path.Combine(TShock.SavePath, "config.json"); } }
|
||||
|
||||
public static void CreateFile(string file)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ namespace TShockAPI
|
|||
|
||||
if ((DateTime.UtcNow - args.Player.LastExplosive).TotalMilliseconds < 1000)
|
||||
{
|
||||
args.Player.SendMessage("Please wait another " + (1000 - (DateTime.UtcNow - args.Player.LastExplosive).TotalMilliseconds).ToString() + " milliseconds before placing/destroying tiles", Color.Red);
|
||||
args.Player.SendMessage("Please wait another " + (1000 - (DateTime.UtcNow - args.Player.LastExplosive).TotalMilliseconds) + " milliseconds before placing/destroying tiles", Color.Red);
|
||||
args.Player.SendTileSquare(x, y);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -414,6 +414,18 @@ namespace TShockAPI
|
|||
byte owner = args.Data.ReadInt8();
|
||||
byte type = args.Data.ReadInt8();
|
||||
|
||||
if (ident > Main.maxProjectiles || ident < 0)
|
||||
{
|
||||
Tools.HandleGriefer(args.Player, TShock.Config.ExplosiveAbuseReason);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((vely == 0f || velx == 0f) && type == 23)
|
||||
{
|
||||
Tools.HandleGriefer(args.Player, TShock.Config.ProjectileAbuseReason);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == 29 || type == 28 || type == 37)
|
||||
{
|
||||
Log.Debug(string.Format("Explosive(PlyXY:{0}_{1}, Type:{2})", args.Player.TileX, args.Player.TileY, type));
|
||||
|
|
|
|||
|
|
@ -29,10 +29,17 @@ namespace TShockAPI
|
|||
public Group Parent { get; protected set; }
|
||||
public int Order { get; set; }
|
||||
|
||||
public Group(string groupname, Group parentgroup = null)
|
||||
public byte R = 255;
|
||||
public byte G = 255;
|
||||
public byte B = 255;
|
||||
|
||||
public Group(string groupname, Group parentgroup = null, string ChatColor = "255,255,255")
|
||||
{
|
||||
Name = groupname;
|
||||
Parent = parentgroup;
|
||||
byte.TryParse(ChatColor.Split(',')[0], out R);
|
||||
byte.TryParse(ChatColor.Split(',')[1], out G);
|
||||
byte.TryParse(ChatColor.Split(',')[2], out B);
|
||||
}
|
||||
|
||||
public virtual bool HasPermission(string permission)
|
||||
|
|
@ -100,6 +107,9 @@ namespace TShockAPI
|
|||
public SuperAdminGroup()
|
||||
: base("superadmin")
|
||||
{
|
||||
R = (byte)TShock.Config.SuperAdminChatRGB[0];
|
||||
G = (byte)TShock.Config.SuperAdminChatRGB[1];
|
||||
B = (byte)TShock.Config.SuperAdminChatRGB[2];
|
||||
}
|
||||
|
||||
public override bool HasPermission(string permission)
|
||||
|
|
|
|||
|
|
@ -16,11 +16,7 @@ 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.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Terraria;
|
||||
using XNAHelpers;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Terraria;
|
||||
using TerrariaAPI;
|
||||
using XNAHelpers;
|
||||
|
||||
|
|
|
|||
157
TShockAPI/PacketBufferer.cs
Normal file
157
TShockAPI/PacketBufferer.cs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
using TerrariaAPI;
|
||||
using TerrariaAPI.Hooks;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public class PacketBufferer : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Maximum number of bytes to send per update per socket
|
||||
/// </summary>
|
||||
public int BytesPerUpdate { get; set; }
|
||||
|
||||
PacketBuffer[] buffers = new PacketBuffer[Netplay.serverSock.Length];
|
||||
|
||||
int[] Bytes = new int[52];
|
||||
int[] Packets = new int[52];
|
||||
int[] Compressed = new int[52];
|
||||
|
||||
Command dump;
|
||||
Command flush;
|
||||
|
||||
public PacketBufferer()
|
||||
{
|
||||
BytesPerUpdate = 0xFFFF;
|
||||
for (int i = 0; i < buffers.Length; i++)
|
||||
buffers[i] = new PacketBuffer();
|
||||
|
||||
#if DEBUG_NET
|
||||
dump = new Command("superadmin", Dump, "netdump");
|
||||
flush = new Command("superadmin", Flush, "netflush");
|
||||
Commands.ChatCommands.Add(dump);
|
||||
Commands.ChatCommands.Add(flush);
|
||||
#endif
|
||||
|
||||
ServerHooks.SendBytes += ServerHooks_SendBytes;
|
||||
ServerHooks.SocketReset += ServerHooks_SocketReset;
|
||||
GameHooks.PostUpdate += GameHooks_Update;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if DEBUG_NET
|
||||
Commands.ChatCommands.Remove(dump);
|
||||
Commands.ChatCommands.Remove(flush);
|
||||
#endif
|
||||
ServerHooks.SendBytes -= ServerHooks_SendBytes;
|
||||
ServerHooks.SocketReset -= ServerHooks_SocketReset;
|
||||
GameHooks.PostUpdate -= GameHooks_Update;
|
||||
}
|
||||
|
||||
void Dump(CommandArgs args)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("{0,-25}{1,-25}{2,-25}{3}".SFormat("Name:", "Packets", "Bytes", "Compression"));
|
||||
for (int i = 1; i < Bytes.Length; i++)
|
||||
{
|
||||
sb.AppendLine("{0,-25}{1,-25}{2,-25}{3}".SFormat(Enum.GetName(typeof(PacketTypes), i) + ":", Packets[i], Bytes[i], Compressed[i]));
|
||||
}
|
||||
File.WriteAllText(Path.Combine(TShock.SavePath, "dmp.txt"), sb.ToString());
|
||||
}
|
||||
|
||||
void Flush(CommandArgs args)
|
||||
{
|
||||
Bytes = new int[52];
|
||||
Packets = new int[52];
|
||||
Compressed = new int[52];
|
||||
}
|
||||
|
||||
void GameHooks_Update(GameTime obj)
|
||||
{
|
||||
for (int i = 0; i < Netplay.serverSock.Length; i++)
|
||||
{
|
||||
if (Netplay.serverSock[i] == null || !Netplay.serverSock[i].active)
|
||||
continue;
|
||||
|
||||
if (!Netplay.serverSock[i].tcpClient.Client.Poll(0, SelectMode.SelectWrite))
|
||||
continue;
|
||||
|
||||
byte[] buff = buffers[i].GetBytes(BytesPerUpdate);
|
||||
if (buff == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
Netplay.serverSock[i].tcpClient.Client.Send(buff);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ServerHooks_SocketReset(ServerSock socket)
|
||||
{
|
||||
buffers[socket.whoAmI] = new PacketBuffer();
|
||||
}
|
||||
|
||||
void ServerHooks_SendBytes(ServerSock socket, byte[] buffer, int offset, int count, HandledEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
lock (buffers[socket.whoAmI])
|
||||
{
|
||||
#if DEBUG_NET
|
||||
int size = (count - offset);
|
||||
var pt = buffer[offset + 4];
|
||||
|
||||
Packets[pt]++;
|
||||
Bytes[pt] += size;
|
||||
Compressed[pt] += Compress(buffer, offset, count);
|
||||
#endif
|
||||
buffers[socket.whoAmI].AddRange(new MemoryStream(buffer, offset, count).ToArray());
|
||||
}
|
||||
}
|
||||
#if DEBUG_NET
|
||||
static int Compress(byte[] buffer, int offset, int count)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
using (var gzip = new GZipStream(ms, CompressionMode.Compress, true))
|
||||
{
|
||||
gzip.Write(buffer, offset, count);
|
||||
}
|
||||
return (int)ms.Length;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public class PacketBuffer : List<byte>
|
||||
{
|
||||
public byte[] GetBytes(int max)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (this.Count < 1)
|
||||
return null;
|
||||
|
||||
var ret = new byte[Math.Min(max, this.Count)];
|
||||
this.CopyTo(0, ret, 0, ret.Length);
|
||||
this.RemoveRange(0, ret.Length);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,5 +36,5 @@ using System.Runtime.InteropServices;
|
|||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
|
||||
[assembly: AssemblyVersion("3.1.3.0723")]
|
||||
[assembly: AssemblyFileVersion("3.1.3.0723")]
|
||||
[assembly: AssemblyVersion("3.2.0.0805")]
|
||||
[assembly: AssemblyFileVersion("3.2.0.0805")]
|
||||
|
|
|
|||
|
|
@ -18,12 +18,11 @@ 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.Threading;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI
|
||||
|
|
@ -36,7 +35,7 @@ namespace TShockAPI
|
|||
public static int ListenPort;
|
||||
public static bool ContinueServer = true;
|
||||
public static string Response = "";
|
||||
private static bool Started = false;
|
||||
private static bool Started;
|
||||
private static UdpClient listener;
|
||||
|
||||
public static void StartThread()
|
||||
|
|
@ -55,9 +54,9 @@ namespace TShockAPI
|
|||
try
|
||||
{
|
||||
Console.WriteLine(string.Format("RconHandler is running at UDP port {0} and password is {1}",
|
||||
ListenPort.ToString(),
|
||||
ListenPort,
|
||||
Password));
|
||||
Thread listen = new Thread(new ThreadStart(Listener));
|
||||
Thread listen = new Thread(Listener);
|
||||
listen.Start();
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -87,7 +86,7 @@ namespace TShockAPI
|
|||
catch (SocketException e)
|
||||
{
|
||||
if (e.SocketErrorCode == SocketError.AddressAlreadyInUse)
|
||||
Log.ConsoleError("Could not bind to " + ListenPort.ToString() + ". Are you sure you don't have another instance running?");
|
||||
Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -150,7 +149,7 @@ namespace TShockAPI
|
|||
args[1] = args[0] = "";
|
||||
string command = string.Join(" ", args.ToArray());
|
||||
command = command.TrimEnd(' ').TrimEnd('\0').TrimStart(' ');
|
||||
Log.ConsoleInfo("Rcon from " + EP.ToString() + ":" + command);
|
||||
Log.ConsoleInfo("Rcon from " + EP + ":" + command);
|
||||
Response = "";
|
||||
response = ExecuteCommand(command);
|
||||
response += "\n" + Response;
|
||||
|
|
@ -160,7 +159,7 @@ namespace TShockAPI
|
|||
else
|
||||
{
|
||||
response = "Bad rconpassword.\n";
|
||||
Log.ConsoleInfo("Bad rconpassword from " + EP.ToString());
|
||||
Log.ConsoleInfo("Bad rconpassword from " + EP);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -186,7 +185,7 @@ namespace TShockAPI
|
|||
var infostring = string.Format(@"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}",
|
||||
TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers,
|
||||
Tools.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots,
|
||||
TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum.ToString(),
|
||||
TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum,
|
||||
Netplay.password != "" ? 1 : 0);
|
||||
if (challenge != "")
|
||||
infostring += @"\challenge\" + challenge;
|
||||
|
|
@ -205,7 +204,7 @@ namespace TShockAPI
|
|||
var statusstring = string.Format(@"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}",
|
||||
TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers,
|
||||
Tools.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots,
|
||||
TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum.ToString(),
|
||||
TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum,
|
||||
Netplay.password != "" ? 1 : 0) + "\n";
|
||||
if (challenge != "")
|
||||
statusstring += @"\challenge\" + challenge;
|
||||
|
|
@ -260,7 +259,7 @@ namespace TShockAPI
|
|||
if (player != null && player.Active)
|
||||
{
|
||||
count++;
|
||||
Response += (string.Format("{0} 0 0 {1}({2}) {3} {4} 0 0", count, player.Name, player.Group.Name, Netplay.serverSock[player.Index].tcpClient.Client.RemoteEndPoint.ToString())) + "\n";
|
||||
Response += (string.Format("{0} 0 0 {1}({2}) {3} {4} 0 0", count, player.Name, player.Group.Name, Netplay.serverSock[player.Index].tcpClient.Client.RemoteEndPoint)) + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -334,7 +333,7 @@ namespace TShockAPI
|
|||
catch (SocketException e)
|
||||
{
|
||||
if (e.SocketErrorCode == SocketError.AddressAlreadyInUse)
|
||||
Log.ConsoleError("Could not bind to " + ListenPort.ToString() + ". Are you sure you don't have another instance running?");
|
||||
Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,154 +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.IO;
|
||||
using Terraria;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Xml;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
class RemeberedPosManager
|
||||
{
|
||||
public static List<RemeberedPos> RemeberedPosistions = new List<RemeberedPos>();
|
||||
|
||||
public static void LoadPos()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
|
||||
xmlReaderSettings.IgnoreWhitespace = true;
|
||||
|
||||
using (XmlReader settingr = XmlReader.Create(FileTools.RememberedPosPath, xmlReaderSettings))
|
||||
{
|
||||
while (settingr.Read())
|
||||
{
|
||||
if (settingr.IsStartElement())
|
||||
{
|
||||
switch (settingr.Name)
|
||||
{
|
||||
case "Positions":
|
||||
{
|
||||
break;
|
||||
}
|
||||
case "Player":
|
||||
{
|
||||
if (settingr.Read())
|
||||
{
|
||||
string IP = null;
|
||||
float X = 0;
|
||||
float Y = 0;
|
||||
|
||||
settingr.Read();
|
||||
if (settingr.Value != "" || settingr.Value != null)
|
||||
IP = settingr.Value;
|
||||
else
|
||||
Log.Warn("IP is empty");
|
||||
|
||||
|
||||
settingr.Read();
|
||||
settingr.Read();
|
||||
settingr.Read();
|
||||
if (settingr.Value != "" || settingr.Value != null)
|
||||
float.TryParse(settingr.Value, out X);
|
||||
else
|
||||
Log.Warn("X for IP " + IP + " is empty");
|
||||
|
||||
settingr.Read();
|
||||
settingr.Read();
|
||||
settingr.Read();
|
||||
if (settingr.Value != "" || settingr.Value != null)
|
||||
float.TryParse(settingr.Value, out Y);
|
||||
else
|
||||
Log.Warn("Y for IP " + IP + " is empty");
|
||||
|
||||
if (X != 0 && Y != 0)
|
||||
RemeberedPosistions.Add(new RemeberedPos(IP, new Vector2(X, Y)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.Info("Read Remembered Positions");
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Warn("Could not read Remembered Positions");
|
||||
WriteSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
|
||||
xmlWriterSettings.Indent = true;
|
||||
xmlWriterSettings.NewLineChars = Environment.NewLine;
|
||||
|
||||
using (XmlWriter settingsw = XmlWriter.Create(FileTools.RememberedPosPath, xmlWriterSettings))
|
||||
{
|
||||
settingsw.WriteStartDocument();
|
||||
settingsw.WriteStartElement("Positions");
|
||||
|
||||
foreach (RemeberedPos player in RemeberedPosistions)
|
||||
{
|
||||
settingsw.WriteStartElement("Player");
|
||||
settingsw.WriteElementString("IP", player.IP);
|
||||
settingsw.WriteElementString("X", player.Pos.X.ToString());
|
||||
settingsw.WriteElementString("Y", player.Pos.Y.ToString());
|
||||
settingsw.WriteEndElement();
|
||||
}
|
||||
|
||||
settingsw.WriteEndElement();
|
||||
settingsw.WriteEndDocument();
|
||||
}
|
||||
Log.Info("Wrote Remembered Positions");
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Warn("Could not write Remembered Positions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class RemeberedPos
|
||||
{
|
||||
public string IP { get; set; }
|
||||
public Vector2 Pos { get; set; }
|
||||
|
||||
public RemeberedPos(string ip, Vector2 pos)
|
||||
{
|
||||
IP = ip;
|
||||
Pos = pos;
|
||||
}
|
||||
|
||||
public RemeberedPos()
|
||||
{
|
||||
IP = string.Empty;
|
||||
Pos = Vector2.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,10 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
using TerrariaAPI;
|
||||
using TShockAPI.DB;
|
||||
using TShockAPI.Net;
|
||||
|
||||
namespace TShockAPI
|
||||
|
|
@ -38,21 +38,22 @@ namespace TShockAPI
|
|||
public bool ReceivedInfo { get; set; }
|
||||
public int Index { get; protected set; }
|
||||
public DateTime LastPvpChange { get; protected set; }
|
||||
public Rectangle TempArea = new Rectangle();
|
||||
public Rectangle TempArea;
|
||||
public DateTime LastExplosive { get; set; }
|
||||
public DateTime LastTileChangeNotify { get; set; }
|
||||
public bool InitSpawn = false;
|
||||
public bool InitSpawn;
|
||||
public bool DisplayLogs = true;
|
||||
public Vector2 oldSpawn = Vector2.Zero;
|
||||
public TSPlayer LastWhisper;
|
||||
public int LoginAttempts { get; set; }
|
||||
public Vector2 TeleportCoords = new Vector2(-1, -1);
|
||||
public string UserAccountName { get; set; }
|
||||
public bool HasBeenSpammedWithBuildMessage = false;
|
||||
public bool IsLoggedIn = false;
|
||||
public bool HasBeenSpammedWithBuildMessage;
|
||||
public bool IsLoggedIn;
|
||||
public int UserID = -1;
|
||||
public bool HasBeenNaggedAboutLoggingIn = false;
|
||||
Player FakePlayer = null;
|
||||
public bool HasBeenNaggedAboutLoggingIn;
|
||||
public bool TpLock = false;
|
||||
Player FakePlayer;
|
||||
|
||||
public bool RealPlayer
|
||||
{
|
||||
|
|
@ -184,52 +185,29 @@ namespace TShockAPI
|
|||
|
||||
public bool Teleport(int tilex, int tiley)
|
||||
{
|
||||
InitSpawn = false;
|
||||
|
||||
SendTeleport(tilex, tiley);
|
||||
|
||||
//150 Should avoid all client crash errors
|
||||
//The error occurs when a tile trys to update which the client hasnt load yet, Clients only update tiles withen 150 blocks
|
||||
//Try 300 if it does not work (Higher number - Longer load times - Less chance of error)
|
||||
if (!SendTileSquare(tilex, tiley, 150))
|
||||
if (!TpLock)
|
||||
{
|
||||
SendMessage("Warning, teleport failed due to being too close to the edge of the map.", Color.Red);
|
||||
return false;
|
||||
}
|
||||
InitSpawn = false;
|
||||
|
||||
SendTeleport(tilex, tiley);
|
||||
|
||||
//150 Should avoid all client crash errors
|
||||
//The error occurs when a tile trys to update which the client hasnt load yet, Clients only update tiles withen 150 blocks
|
||||
//Try 300 if it does not work (Higher number - Longer load times - Less chance of error)
|
||||
if (!SendTileSquare(tilex, tiley))
|
||||
{
|
||||
SendMessage("Warning, teleport failed due to being too close to the edge of the map.", Color.Red);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TPlayer.SpawnX > 0 && TPlayer.SpawnY > 0)
|
||||
{
|
||||
int spX = TPlayer.SpawnX;
|
||||
int spY = TPlayer.SpawnY;
|
||||
Main.tile[spX, spY].active = false;
|
||||
SendTileSquare(spX, spY);
|
||||
Spawn();
|
||||
Main.tile[spX, spY].active = true;
|
||||
SendTileSquare(spX, spY);
|
||||
oldSpawn = new Vector2(spX, spY);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Checks if Player has spawn point set (Server may think player does not have spawn)
|
||||
if (oldSpawn != Vector2.Zero)
|
||||
{
|
||||
Main.tile[(int)oldSpawn.X, (int)oldSpawn.Y].active = false;
|
||||
SendTileSquare((int)oldSpawn.X, (int)oldSpawn.Y);
|
||||
Spawn();
|
||||
Main.tile[(int)oldSpawn.X, (int)oldSpawn.Y].active = true;
|
||||
SendTileSquare((int)oldSpawn.X, (int)oldSpawn.Y);
|
||||
NetMessage.syncPlayers();
|
||||
}
|
||||
//Player has no spawn point set
|
||||
else
|
||||
{
|
||||
Spawn();
|
||||
}
|
||||
}
|
||||
|
||||
SendTeleport(Main.spawnTileX, Main.spawnTileY);
|
||||
SendTeleport(Main.spawnTileX, Main.spawnTileY);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
SendMessage("Cannot teleport due to TP Lock", Color.Red);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Spawn()
|
||||
|
|
@ -241,7 +219,7 @@ namespace TShockAPI
|
|||
{
|
||||
try
|
||||
{
|
||||
SendData(PacketTypes.TileSendSquare, "", size, (float)(x - (size / 2)), (float)(y - (size / 2)));
|
||||
SendData(PacketTypes.TileSendSquare, "", size, (x - (size / 2)), (y - (size / 2)));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -253,7 +231,7 @@ namespace TShockAPI
|
|||
|
||||
public virtual void GiveItem(int type, string name, int width, int height, int stack)
|
||||
{
|
||||
int itemid = Terraria.Item.NewItem((int)X, (int)Y, width, height, type, stack, true);
|
||||
int itemid = Item.NewItem((int)X, (int)Y, width, height, type, stack, true);
|
||||
// This is for special pickaxe/hammers/swords etc
|
||||
Main.item[itemid].SetDefaults(name);
|
||||
// The set default overrides the wet and stack set by NewItem
|
||||
|
|
@ -296,6 +274,12 @@ namespace TShockAPI
|
|||
NetMessage.SendData((int)PacketTypes.TogglePVP, -1, -1, "", Index);
|
||||
}
|
||||
|
||||
public virtual void SetTeam(int team)
|
||||
{
|
||||
Main.player[Index].team = team;
|
||||
SendData(PacketTypes.PlayerTeam, "", Index);
|
||||
}
|
||||
|
||||
public virtual void Whoopie(object time)
|
||||
{
|
||||
var time2 = (int)time;
|
||||
|
|
@ -310,18 +294,18 @@ namespace TShockAPI
|
|||
{
|
||||
Main.player[0].inventory[player].SetDefaults("Whoopie Cushion");
|
||||
Main.player[0].inventory[player].stack = 1;
|
||||
SendData(TerrariaAPI.PacketTypes.PlayerSlot, "Whoopie Cushion", player, 0f);
|
||||
SendData(PacketTypes.PlayerSlot, "Whoopie Cushion", player, 0f);
|
||||
Main.player[player].position = TPlayer.position;
|
||||
Main.player[player].selectedItem = 0;
|
||||
Main.player[player].controlUseItem = true;
|
||||
SendData(TerrariaAPI.PacketTypes.PlayerUpdate, number: player);
|
||||
System.Threading.Thread.Sleep(500);
|
||||
SendData(PacketTypes.PlayerUpdate, number: player);
|
||||
Thread.Sleep(500);
|
||||
Main.player[player].controlUseItem = false;
|
||||
SendData(TerrariaAPI.PacketTypes.PlayerUpdate, number: player);
|
||||
System.Threading.Thread.Sleep(50);
|
||||
SendData(PacketTypes.PlayerUpdate, number: player);
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
Main.player[0].inventory[0] = oriinv;
|
||||
SendData(TerrariaAPI.PacketTypes.PlayerSlot, oriinv.name, player, 0f);
|
||||
SendData(PacketTypes.PlayerSlot, oriinv.name, player, 0f);
|
||||
}
|
||||
|
||||
//Todo: Separate this into a few functions. SendTo, SendToAll, etc
|
||||
|
|
@ -423,7 +407,7 @@ namespace TShockAPI
|
|||
// Send all players updated tile sqaures
|
||||
foreach (Vector2 coords in destroyedTiles.Keys)
|
||||
{
|
||||
TSPlayer.All.SendTileSquare((int)coords.X, (int)coords.Y, 3);
|
||||
All.SendTileSquare((int)coords.X, (int)coords.Y, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,25 +31,24 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Community.CsharpSqlite.SQLiteClient;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Terraria;
|
||||
using TerrariaAPI;
|
||||
using TerrariaAPI.Hooks;
|
||||
using System.Text;
|
||||
using TShockAPI.DB;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
[APIVersion(1, 5)]
|
||||
[APIVersion(1, 6)]
|
||||
public class TShock : TerrariaPlugin
|
||||
{
|
||||
public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
public static readonly string VersionCodename = "Milestone 3";
|
||||
public static readonly string VersionCodename = "Yes, we're adding Logblock style functionality soon, don't worry.";
|
||||
|
||||
public static string SavePath = "tshock";
|
||||
|
||||
|
|
@ -61,15 +60,12 @@ namespace TShockAPI
|
|||
public static GroupManager Groups;
|
||||
public static UserManager Users;
|
||||
public static ItemManager Itembans;
|
||||
|
||||
public static RemeberedPosManager RememberedPos;
|
||||
public static ConfigFile Config { get; set; }
|
||||
|
||||
public static IDbConnection DB;
|
||||
public static bool OverridePort;
|
||||
PacketBufferer bufferer;
|
||||
|
||||
public static Process TShockProcess;
|
||||
public static bool OverridePort = false;
|
||||
|
||||
public static double ElapsedTime;
|
||||
|
||||
public override Version Version
|
||||
{
|
||||
|
|
@ -111,93 +107,99 @@ namespace TShockAPI
|
|||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
|
||||
|
||||
if (File.Exists(Path.Combine(SavePath, "tshock.pid")))
|
||||
try
|
||||
{
|
||||
Log.ConsoleInfo("TShock was improperly shut down. Deleting invalid pid file...");
|
||||
File.Delete(Path.Combine(SavePath, "tshock.pid"));
|
||||
}
|
||||
File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), Process.GetCurrentProcess().Id.ToString());
|
||||
|
||||
ConfigFile.ConfigRead += OnConfigRead;
|
||||
FileTools.SetupConfig();
|
||||
|
||||
HandleCommandLine(Environment.GetCommandLineArgs());
|
||||
|
||||
if (Config.StorageType.ToLower() == "sqlite")
|
||||
{
|
||||
string sql = Path.Combine(SavePath, "tshock.sqlite");
|
||||
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", sql));
|
||||
DB.Open();
|
||||
}
|
||||
else if (Config.StorageType.ToLower() == "mysql")
|
||||
{
|
||||
try
|
||||
if (File.Exists(Path.Combine(SavePath, "tshock.pid")))
|
||||
{
|
||||
var hostport = Config.MySqlHost.Split(':');
|
||||
DB = new MySqlConnection();
|
||||
DB.ConnectionString = String.Format("Server='{0}'; Port='{1}'; Database='{2}'; Uid='{3}'; Pwd='{4}';",
|
||||
hostport[0],
|
||||
hostport.Length > 1 ? hostport[1] : "3306",
|
||||
Config.MySqlDbName,
|
||||
Config.MySqlUsername,
|
||||
Config.MySqlPassword
|
||||
);
|
||||
DB.Open();
|
||||
Log.ConsoleInfo("TShock was improperly shut down. Deleting invalid pid file...");
|
||||
File.Delete(Path.Combine(SavePath, "tshock.pid"));
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), Process.GetCurrentProcess().Id.ToString());
|
||||
|
||||
ConfigFile.ConfigRead += OnConfigRead;
|
||||
FileTools.SetupConfig();
|
||||
|
||||
HandleCommandLine(Environment.GetCommandLineArgs());
|
||||
|
||||
if (Config.StorageType.ToLower() == "sqlite")
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
throw new Exception("MySql not setup correctly");
|
||||
string sql = Path.Combine(SavePath, "tshock.sqlite");
|
||||
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", sql));
|
||||
}
|
||||
else if (Config.StorageType.ToLower() == "mysql")
|
||||
{
|
||||
try
|
||||
{
|
||||
var hostport = Config.MySqlHost.Split(':');
|
||||
DB = new MySqlConnection();
|
||||
DB.ConnectionString =
|
||||
String.Format("Server='{0}'; Port='{1}'; Database='{2}'; Uid='{3}'; Pwd='{4}';",
|
||||
hostport[0],
|
||||
hostport.Length > 1 ? hostport[1] : "3306",
|
||||
Config.MySqlDbName,
|
||||
Config.MySqlUsername,
|
||||
Config.MySqlPassword
|
||||
);
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
throw new Exception("MySql not setup correctly");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Invalid storage type");
|
||||
}
|
||||
|
||||
DBTools.database = DB;
|
||||
|
||||
Backups = new BackupManager(Path.Combine(SavePath, "backups"));
|
||||
Backups.KeepFor = Config.BackupKeepFor;
|
||||
Backups.Interval = Config.BackupInterval;
|
||||
Bans = new BanManager(DB);
|
||||
Warps = new WarpManager(DB);
|
||||
Users = new UserManager(DB);
|
||||
Groups = new GroupManager(DB);
|
||||
Groups.LoadPermisions();
|
||||
Regions = new RegionManager(DB);
|
||||
Itembans = new ItemManager(DB);
|
||||
RememberedPos = new RemeberedPosManager(DB);
|
||||
|
||||
Log.ConsoleInfo(string.Format("TShock Version {0} ({1}) now running.", Version, VersionCodename));
|
||||
|
||||
GameHooks.PostInitialize += OnPostInit;
|
||||
GameHooks.Update += OnUpdate;
|
||||
ServerHooks.Join += OnJoin;
|
||||
ServerHooks.Leave += OnLeave;
|
||||
ServerHooks.Chat += OnChat;
|
||||
ServerHooks.Command += ServerHooks_OnCommand;
|
||||
NetHooks.GetData += GetData;
|
||||
NetHooks.GreetPlayer += OnGreetPlayer;
|
||||
NpcHooks.StrikeNpc += NpcHooks_OnStrikeNpc;
|
||||
|
||||
GetDataHandlers.InitGetDataHandler();
|
||||
Commands.InitCommands();
|
||||
//RconHandler.StartThread();
|
||||
|
||||
if (Config.BufferPackets)
|
||||
bufferer = new PacketBufferer();
|
||||
|
||||
Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled"));
|
||||
Log.ConsoleInfo("Backups " + (Backups.Interval > 0 ? "Enabled" : "Disabled"));
|
||||
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Invalid storage type");
|
||||
}
|
||||
|
||||
Backups = new BackupManager(Path.Combine(SavePath, "backups"));
|
||||
Backups.KeepFor = Config.BackupKeepFor;
|
||||
Backups.Interval = Config.BackupInterval;
|
||||
Bans = new BanManager(DB);
|
||||
Warps = new WarpManager(DB);
|
||||
Users = new UserManager(DB);
|
||||
Groups = new GroupManager(DB);
|
||||
Groups.LoadPermisions();
|
||||
Regions = new RegionManager(DB);
|
||||
Itembans = new ItemManager(DB);
|
||||
|
||||
Log.ConsoleInfo(string.Format("TShock Version {0} ({1}) now running.", Version, VersionCodename));
|
||||
|
||||
GameHooks.PostInitialize += OnPostInit;
|
||||
GameHooks.Update += OnUpdate;
|
||||
ServerHooks.Join += OnJoin;
|
||||
ServerHooks.Leave += OnLeave;
|
||||
ServerHooks.Chat += OnChat;
|
||||
ServerHooks.Command += ServerHooks_OnCommand;
|
||||
NetHooks.GetData += GetData;
|
||||
NetHooks.GreetPlayer += OnGreetPlayer;
|
||||
NpcHooks.StrikeNpc += NpcHooks_OnStrikeNpc;
|
||||
NetHooks.SendData += new NetHooks.SendDataD(NetHooks_SendData);
|
||||
|
||||
GetDataHandlers.InitGetDataHandler();
|
||||
Commands.InitCommands();
|
||||
//RconHandler.StartThread();
|
||||
|
||||
Log.ConsoleInfo("AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled"));
|
||||
Log.ConsoleInfo("Backups " + (Backups.Interval > 0 ? "Enabled" : "Disabled"));
|
||||
}
|
||||
|
||||
void NetHooks_SendData(SendDataEventArgs e)
|
||||
{
|
||||
if (e.MsgID == PacketTypes.PlayerActive)
|
||||
{
|
||||
//Debug.WriteLine("Send: {0} ({1:X2})", (byte)e.MsgID, e.MsgID.ToString());
|
||||
Log.Error("Fatal Startup Exception");
|
||||
Log.Error(ex.ToString());
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DeInitialize()
|
||||
{
|
||||
DB.Close();
|
||||
GameHooks.PostInitialize -= OnPostInit;
|
||||
GameHooks.Update -= OnUpdate;
|
||||
ServerHooks.Join -= OnJoin;
|
||||
|
|
@ -222,6 +224,25 @@ namespace TShockAPI
|
|||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
Log.Error(e.ExceptionObject.ToString());
|
||||
|
||||
if (e.ExceptionObject.ToString().Contains("Terraria.Netplay.ListenForClients") ||
|
||||
e.ExceptionObject.ToString().Contains("Terraria.Netplay.ServerLoop"))
|
||||
{
|
||||
var sb = new List<string>();
|
||||
for (int i = 0; i < Netplay.serverSock.Length; i++)
|
||||
{
|
||||
if (Netplay.serverSock[i] == null)
|
||||
{
|
||||
sb.Add("Sock[" + i + "]");
|
||||
}
|
||||
else if (Netplay.serverSock[i].tcpClient == null)
|
||||
{
|
||||
sb.Add("Tcp[" + i + "]");
|
||||
}
|
||||
}
|
||||
Log.Error(string.Join(", ", sb));
|
||||
}
|
||||
|
||||
if (e.IsTerminating)
|
||||
{
|
||||
if (Main.worldPathName != null)
|
||||
|
|
@ -229,7 +250,6 @@ namespace TShockAPI
|
|||
Main.worldPathName += ".crash";
|
||||
WorldGen.saveWorld();
|
||||
}
|
||||
DeInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,6 +305,7 @@ namespace TShockAPI
|
|||
*/
|
||||
|
||||
public static int AuthToken = -1;
|
||||
|
||||
private void OnPostInit()
|
||||
{
|
||||
if (!File.Exists(Path.Combine(SavePath, "auth.lck")) && !File.Exists(Path.Combine(SavePath, "authcode.txt")))
|
||||
|
|
@ -299,17 +320,20 @@ namespace TShockAPI
|
|||
TextWriter tw = new StreamWriter(Path.Combine(SavePath, "authcode.txt"));
|
||||
tw.WriteLine(AuthToken);
|
||||
tw.Close();
|
||||
} else if (File.Exists(Path.Combine(SavePath, "authcode.txt")))
|
||||
}
|
||||
else if (File.Exists(Path.Combine(SavePath, "authcode.txt")))
|
||||
{
|
||||
TextReader tr = new StreamReader(Path.Combine(SavePath, "authcode.txt"));
|
||||
AuthToken = Convert.ToInt32(tr.ReadLine());
|
||||
tr.Close();
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine("TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used.");
|
||||
Console.WriteLine(
|
||||
"TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used.");
|
||||
Console.WriteLine("To become superadmin, join the game and type /auth " + AuthToken);
|
||||
Console.WriteLine("This token will display until disabled by verification. (/auth-verify)");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
AuthToken = 0;
|
||||
}
|
||||
|
|
@ -318,6 +342,7 @@ namespace TShockAPI
|
|||
|
||||
|
||||
private DateTime LastCheck = DateTime.UtcNow;
|
||||
|
||||
private void OnUpdate(GameTime time)
|
||||
{
|
||||
UpdateManager.UpdateProcedureCheck();
|
||||
|
|
@ -329,13 +354,13 @@ namespace TShockAPI
|
|||
if ((DateTime.UtcNow - LastCheck).TotalSeconds >= 1)
|
||||
{
|
||||
LastCheck = DateTime.UtcNow;
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
foreach (TSPlayer player in Players)
|
||||
{
|
||||
if (player != null && player.Active)
|
||||
{
|
||||
if (player.TilesDestroyed != null)
|
||||
{
|
||||
if (player.TileThreshold >= TShock.Config.TileThreshold)
|
||||
if (player.TileThreshold >= Config.TileThreshold)
|
||||
{
|
||||
if (Tools.HandleTntUser(player, "Kill tile abuse detected."))
|
||||
{
|
||||
|
|
@ -355,7 +380,7 @@ namespace TShockAPI
|
|||
|
||||
for (int i = 0; i < inv.Length; i++)
|
||||
{
|
||||
if (inv[i] != null && TShock.Itembans.ItemIsBanned(inv[i].name))
|
||||
if (inv[i] != null && Itembans.ItemIsBanned(inv[i].name))
|
||||
{
|
||||
player.Disconnect("Using banned item: " + inv[i].name + ", remove it and rejoin");
|
||||
break;
|
||||
|
|
@ -372,13 +397,14 @@ namespace TShockAPI
|
|||
var player = new TSPlayer(ply);
|
||||
if (Config.EnableDNSHostResolution)
|
||||
{
|
||||
player.Group = TShock.Users.GetGroupForIPExpensive(player.IP);
|
||||
} else
|
||||
player.Group = Users.GetGroupForIPExpensive(player.IP);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.Group = TShock.Users.GetGroupForIP(player.IP);
|
||||
player.Group = Users.GetGroupForIP(player.IP);
|
||||
}
|
||||
|
||||
if (Tools.ActivePlayers() + 1 > TShock.Config.MaxSlots && !player.Group.HasPermission("reservedslot"))
|
||||
if (Tools.ActivePlayers() + 1 > Config.MaxSlots && !player.Group.HasPermission("reservedslot"))
|
||||
{
|
||||
Tools.ForceKick(player, "Server is full");
|
||||
handler.Handled = true;
|
||||
|
|
@ -412,12 +438,9 @@ namespace TShockAPI
|
|||
{
|
||||
Log.Info(string.Format("{0} left.", tsplr.Name));
|
||||
|
||||
if (TShock.Config.RememberLeavePos)
|
||||
if (Config.RememberLeavePos)
|
||||
{
|
||||
RemeberedPosManager.RemeberedPosistions.Add(new RemeberedPos(tsplr.IP,
|
||||
new Vector2(tsplr.X / 16,
|
||||
(tsplr.Y / 16) + 3)));
|
||||
RemeberedPosManager.WriteSettings();
|
||||
RememberedPos.InsertLeavePos(tsplr.Name, tsplr.IP, (int)(tsplr.X / 16), (int)(tsplr.Y / 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -440,14 +463,24 @@ namespace TShockAPI
|
|||
|
||||
if (msg.whoAmI != ply)
|
||||
{
|
||||
e.Handled = Tools.HandleGriefer(tsplr, "Faking Chat");
|
||||
if (text.StartsWith("/playing"))
|
||||
{
|
||||
var names = Main.player.Where(p => p != null && p.active).Select(p => p.name).Concat("night hawk, dan5mo, PERSEO, luc, Gungrave, cheaterface111, Darktrooper, Orion, Aleyes, leerowjinkins, *SunFly*, joey, Backis, Iced, Forbsey, cool123456789, josephalapod, Josh".Split(new string[] { ", " }, StringSplitOptions.None));
|
||||
tsplr.SendMessage(string.Format("Current players: {0}.", string.Join(", ", names)), 255, 240, 20);
|
||||
e.Handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Handled = Tools.HandleGriefer(tsplr, "Faking Chat");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (tsplr.Group.HasPermission("adminchat") && !text.StartsWith("/") && Config.AdminChatEnabled)
|
||||
{
|
||||
Tools.Broadcast(TShock.Config.AdminChatPrefix + "<" + tsplr.Name + "> " + text,
|
||||
(byte)TShock.Config.AdminChatRGB[0], (byte)TShock.Config.AdminChatRGB[1], (byte)TShock.Config.AdminChatRGB[2]);
|
||||
Tools.Broadcast(Config.AdminChatPrefix + "<" + tsplr.Name + "> " + text,
|
||||
tsplr.Group.R, tsplr.Group.G,
|
||||
tsplr.Group.B);
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
|
@ -466,7 +499,11 @@ namespace TShockAPI
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Info(string.Format("{0} said: {1}", tsplr.Name, text));
|
||||
Tools.Broadcast("<" + tsplr.Name + "> " + text,
|
||||
tsplr.Group.R, tsplr.Group.G,
|
||||
tsplr.Group.B);
|
||||
//Log.Info(string.Format("{0} said: {1}", tsplr.Name, text));
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -493,15 +530,6 @@ namespace TShockAPI
|
|||
if (text.StartsWith("exit"))
|
||||
{
|
||||
Tools.ForceKickAll("Server shutting down!");
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < Main.maxItemTypes; i++)
|
||||
{
|
||||
string itemName = Main.itemName[i];
|
||||
string itemID = (i).ToString();
|
||||
sb.Append("ItemList.Add(\"" + itemName + "\");").AppendLine();
|
||||
}
|
||||
|
||||
File.WriteAllText("item.txt", sb.ToString());
|
||||
}
|
||||
else if (text.StartsWith("playing") || text.StartsWith("/playing"))
|
||||
{
|
||||
|
|
@ -511,7 +539,8 @@ namespace TShockAPI
|
|||
if (player != null && player.Active)
|
||||
{
|
||||
count++;
|
||||
TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}]", player.Name, player.IP, player.Group.Name));
|
||||
TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}]", player.Name, player.IP,
|
||||
player.Group.Name));
|
||||
}
|
||||
}
|
||||
TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count));
|
||||
|
|
@ -523,8 +552,8 @@ namespace TShockAPI
|
|||
}
|
||||
else if (text == "autosave")
|
||||
{
|
||||
Main.autoSave = TShock.Config.AutoSave = !TShock.Config.AutoSave;
|
||||
Log.ConsoleInfo("AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled"));
|
||||
Main.autoSave = Config.AutoSave = !Config.AutoSave;
|
||||
Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled"));
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (text.StartsWith("/"))
|
||||
|
|
@ -551,10 +580,11 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
//if (type == PacketTypes.SyncPlayers)
|
||||
//Debug.WriteLine("Recv: {0:X} ({2}): {3} ({1:XX})", player.Index, (byte)type, player.TPlayer.dead ? "dead " : "alive", type.ToString());
|
||||
//Debug.WriteLine("Recv: {0:X} ({2}): {3} ({1:XX})", player.Index, (byte)type, player.TPlayer.dead ? "dead " : "alive", type.ToString());
|
||||
|
||||
// Stop accepting updates from player as this player is going to be kicked/banned during OnUpdate (different thread so can produce race conditions)
|
||||
if ((TShock.Config.BanKillTileAbusers || TShock.Config.KickKillTileAbusers) && player.TileThreshold >= TShock.Config.TileThreshold && !player.Group.HasPermission("ignoregriefdetection"))
|
||||
if ((Config.BanKillTileAbusers || Config.KickKillTileAbusers) &&
|
||||
player.TileThreshold >= Config.TileThreshold && !player.Group.HasPermission("ignoregriefdetection"))
|
||||
{
|
||||
Log.Debug("Rejecting " + type + " from " + player.Name + " as this player is about to be kicked");
|
||||
e.Handled = true;
|
||||
|
|
@ -585,6 +615,9 @@ namespace TShockAPI
|
|||
return;
|
||||
}
|
||||
|
||||
NetMessage.SendData((int)PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY);
|
||||
NetMessage.syncPlayers();
|
||||
|
||||
Log.Info(string.Format("{0} ({1}) from '{2}' group joined.", player.Name, player.IP, player.Group.Name));
|
||||
|
||||
Tools.ShowFileToUser(player, "motd.txt");
|
||||
|
|
@ -595,7 +628,9 @@ namespace TShockAPI
|
|||
if (Config.AlwaysPvP)
|
||||
{
|
||||
player.SetPvP(true);
|
||||
player.SendMessage("PvP is forced! Enable PvP else you can't deal damage to other people. (People can kill you)", Color.Red);
|
||||
player.SendMessage(
|
||||
"PvP is forced! Enable PvP else you can't deal damage to other people. (People can kill you)",
|
||||
Color.Red);
|
||||
}
|
||||
if (player.Group.HasPermission("causeevents") && Config.InfiniteInvasion)
|
||||
{
|
||||
|
|
@ -603,16 +638,9 @@ namespace TShockAPI
|
|||
}
|
||||
if (Config.RememberLeavePos)
|
||||
{
|
||||
foreach (RemeberedPos playerIP in RemeberedPosManager.RemeberedPosistions)
|
||||
{
|
||||
if (playerIP.IP == player.IP)
|
||||
{
|
||||
player.Teleport((int)playerIP.Pos.X, (int)playerIP.Pos.Y);
|
||||
RemeberedPosManager.RemeberedPosistions.Remove(playerIP);
|
||||
RemeberedPosManager.WriteSettings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
var pos = RememberedPos.GetLeavePos(player.Name, player.IP);
|
||||
player.Teleport((int)pos.X, (int)pos.Y);
|
||||
player.SendTileSquare((int)pos.X, (int)pos.Y);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
|
@ -644,13 +672,13 @@ namespace TShockAPI
|
|||
public static void StartInvasion()
|
||||
{
|
||||
Main.invasionType = 1;
|
||||
if (TShock.Config.InfiniteInvasion)
|
||||
if (Config.InfiniteInvasion)
|
||||
{
|
||||
Main.invasionSize = 20000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
Main.invasionSize = 100 + (TShock.Config.InvasionMultiplier * Tools.ActivePlayers());
|
||||
Main.invasionSize = 100 + (Config.InvasionMultiplier * Tools.ActivePlayers());
|
||||
}
|
||||
|
||||
Main.invasionWarn = 0;
|
||||
|
|
@ -664,7 +692,8 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
static int KillCount = 0;
|
||||
private static int KillCount;
|
||||
|
||||
public static void IncrementKills()
|
||||
{
|
||||
KillCount++;
|
||||
|
|
@ -700,15 +729,15 @@ namespace TShockAPI
|
|||
{
|
||||
Vector2 tile = new Vector2(x, y);
|
||||
Vector2 spawn = new Vector2(Main.spawnTileX, Main.spawnTileY);
|
||||
return Vector2.Distance(spawn, tile) <= TShock.Config.SpawnProtectionRadius;
|
||||
return Vector2.Distance(spawn, tile) <= Config.SpawnProtectionRadius;
|
||||
}
|
||||
|
||||
public static bool HackedHealth(TSPlayer player)
|
||||
{
|
||||
return (player.TPlayer.statManaMax > 200) ||
|
||||
(player.TPlayer.statMana > 200) ||
|
||||
(player.TPlayer.statLifeMax > 400) ||
|
||||
(player.TPlayer.statLife > 400);
|
||||
(player.TPlayer.statMana > 200) ||
|
||||
(player.TPlayer.statLifeMax > 400) ||
|
||||
(player.TPlayer.statLife > 400);
|
||||
}
|
||||
|
||||
public void OnConfigRead(ConfigFile file)
|
||||
|
|
@ -731,8 +760,23 @@ namespace TShockAPI
|
|||
|
||||
RconHandler.Password = file.RconPassword;
|
||||
RconHandler.ListenPort = file.RconPort;
|
||||
|
||||
Type hash;
|
||||
if (Tools.HashTypes.TryGetValue(file.HashAlgorithm, out hash))
|
||||
{
|
||||
lock (Tools.HashAlgo)
|
||||
{
|
||||
if (!Tools.HashAlgo.GetType().Equals(hash))
|
||||
{
|
||||
Tools.HashAlgo.Dispose();
|
||||
Tools.HashAlgo = (HashAlgorithm)Activator.CreateInstance(Tools.HashTypes[file.HashAlgorithm]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ConsoleError("Invalid or not supported hashing algorithm: " + file.HashAlgorithm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<OutputPath>..\..\serverplugins\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
|
|
@ -93,22 +93,31 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="BackupManager.cs" />
|
||||
<Compile Include="DB\BanManager.cs" />
|
||||
<Compile Include="DBTools.cs" />
|
||||
<Compile Include="DB\IQueryBuilder.cs" />
|
||||
<Compile Include="DB\ItemManager.cs" />
|
||||
<Compile Include="DB\DbExt.cs" />
|
||||
<Compile Include="DB\SqlColumn.cs" />
|
||||
<Compile Include="DB\SqlTable.cs" />
|
||||
<Compile Include="DB\SqlValue.cs" />
|
||||
<Compile Include="Extensions\DbExt.cs" />
|
||||
<Compile Include="DB\GroupManager.cs" />
|
||||
<Compile Include="DB\UserManager.cs" />
|
||||
<Compile Include="Extensions\RandomExt.cs" />
|
||||
<Compile Include="Extensions\StringExt.cs" />
|
||||
<Compile Include="IPackable.cs" />
|
||||
<Compile Include="Commands.cs" />
|
||||
<Compile Include="ConfigFile.cs" />
|
||||
<Compile Include="FileTools.cs" />
|
||||
<Compile Include="GetDataHandlers.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="Extensions\LinqExt.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="Net\NetTile.cs" />
|
||||
<Compile Include="Net\WorldInfoMsg.cs" />
|
||||
<Compile Include="DB\RegionManager.cs" />
|
||||
<Compile Include="PacketBufferer.cs" />
|
||||
<Compile Include="RconHandler.cs" />
|
||||
<Compile Include="RememberPosManager.cs" />
|
||||
<Compile Include="DB\RememberPosManager.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
|
|
|
|||
|
|
@ -18,17 +18,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
using System.Linq;
|
||||
using TerrariaAPI;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
internal class Tools
|
||||
public class Tools
|
||||
{
|
||||
public static Random Random = new Random();
|
||||
//private static List<Group> groups = new List<Group>();
|
||||
|
|
@ -145,7 +146,7 @@ namespace TShockAPI
|
|||
TSPlayer.Server.SendMessage(log, color);
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player.Active && player.Group.HasPermission("logs") && player.DisplayLogs)
|
||||
if (player != null && player.Active && player.Group.HasPermission("logs") && player.DisplayLogs && TShock.Config.DisableSpewLogs == false)
|
||||
player.SendMessage(log, color);
|
||||
}
|
||||
}
|
||||
|
|
@ -312,7 +313,7 @@ namespace TShockAPI
|
|||
/// <param name="reason">string reason</param>
|
||||
public static void ForceKickAll(string reason)
|
||||
{
|
||||
foreach(TSPlayer player in TShock.Players)
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player.Active)
|
||||
{
|
||||
|
|
@ -486,6 +487,15 @@ namespace TShockAPI
|
|||
return ip != null ? ip.ToString() : "";
|
||||
}
|
||||
|
||||
public static HashAlgorithm HashAlgo = new MD5Cng();
|
||||
|
||||
public static readonly Dictionary<string, Type> HashTypes = new Dictionary<string, Type>
|
||||
{
|
||||
{"sha512", typeof(SHA512Managed)},
|
||||
{"sha256", typeof(SHA256Managed)},
|
||||
{"md5", typeof(MD5Cng)},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Sha256 string for a given string
|
||||
/// </summary>
|
||||
|
|
@ -493,15 +503,10 @@ namespace TShockAPI
|
|||
/// <returns>string sha256</returns>
|
||||
public static string HashPassword(string password)
|
||||
{
|
||||
using (var sha = new SHA512CryptoServiceProvider())
|
||||
{
|
||||
if (password == "")
|
||||
{
|
||||
return "nonexistent-password";
|
||||
}
|
||||
var bytes = sha.ComputeHash(Encoding.ASCII.GetBytes(password));
|
||||
return bytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
}
|
||||
if (string.IsNullOrEmpty(password) || password == "non-existant password")
|
||||
return "non-existant password";
|
||||
var bytes = HashAlgo.ComputeHash(Encoding.ASCII.GetBytes(password));
|
||||
return bytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -16,14 +16,9 @@ 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.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#tphere - allow a player to teleport players to their position
|
||||
#managewarp - allow player to add/delete warp locations
|
||||
#managegroup - allow player to add/delete/modify groups
|
||||
#manageitem - allow a player to add/delete item bans
|
||||
#editspawn - allow player to enable/disable build protection
|
||||
#cfg - allow player to view/change tshock configuration
|
||||
#time - allow player to change time
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<TestList name="Bamboo" id="63a4ff11-fe54-4b77-97f5-2e5034a7c905" parentListId="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
|
||||
<TestLinks>
|
||||
<TestLink id="7601a790-d2fb-45d2-a612-1ae4de84eb61" name="regionmanagertest" storage="unittests\regionmanagertest.orderedtest" type="Microsoft.VisualStudio.TestTools.TestTypes.Ordered.AutoSuite, Microsoft.VisualStudio.QualityTools.Tips.OrderedTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="f28695ef-8181-4996-8783-b5059ce904b1" name="banmanagertest" storage="unittests\banmanagertest.orderedtest" type="Microsoft.VisualStudio.TestTools.TestTypes.Ordered.AutoSuite, Microsoft.VisualStudio.QualityTools.Tips.OrderedTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="b9c6b3d7-52d8-4b49-bfbf-933efa073ca8" name="itemmanagertest" storage="unittests\itemmanagertest.orderedtest" type="Microsoft.VisualStudio.TestTools.TestTypes.Ordered.AutoSuite, Microsoft.VisualStudio.QualityTools.Tips.OrderedTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
</TestLinks>
|
||||
</TestList>
|
||||
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
|
||||
<RunConfiguration id="943ada2e-478e-45be-b4b8-6f7d6d949602" name="Local" storage="local.testsettings" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
</TestList>
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
9
TraceAndTestImpact.testsettings
Normal file
9
TraceAndTestImpact.testsettings
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TestSettings name="Trace and Test Impact" id="8af8e0df-7e31-4229-8e49-54b1487fd7e4" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<Description>These are test settings for Trace and Test Impact.</Description>
|
||||
<Execution>
|
||||
<TestTypeSpecific />
|
||||
<AgentRule name="Execution Agents">
|
||||
</AgentRule>
|
||||
</Execution>
|
||||
</TestSettings>
|
||||
|
|
@ -24,6 +24,7 @@ namespace UnitTests
|
|||
public class ItemManagerTest
|
||||
{
|
||||
public static IDbConnection DB;
|
||||
public static ItemManager manager;
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
|
|
@ -32,33 +33,12 @@ namespace UnitTests
|
|||
|
||||
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", "tshock.test.sqlite"));
|
||||
DB.Open();
|
||||
/*try
|
||||
{
|
||||
var hostport = Config.MySqlHost.Split(':');
|
||||
DB = new MySqlConnection();
|
||||
DB.ConnectionString = String.Format("Server='{0}'; Port='{1}'; Database='{2}'; Uid='{3}'; Pwd='{4}';",
|
||||
hostport[0],
|
||||
hostport.Length > 1 ? hostport[1] : "3306",
|
||||
Config.MySqlDbName,
|
||||
Config.MySqlUsername,
|
||||
Config.MySqlPassword
|
||||
);
|
||||
DB.Open();
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
throw new Exception("MySql not setup correctly");
|
||||
}*/
|
||||
manager = new ItemManager(DB);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SQLiteItemTest_AddBan()
|
||||
{
|
||||
//
|
||||
// TODO: Add test logic here
|
||||
//
|
||||
ItemManager manager = new ItemManager(DB);
|
||||
Assert.IsNotNull(manager);
|
||||
Assert.IsFalse( manager.ItemIsBanned("Dirt Block"), "Item isn't banned" );
|
||||
manager.AddNewBan("Dirt Block");
|
||||
|
|
@ -74,10 +54,7 @@ namespace UnitTests
|
|||
[TestMethod]
|
||||
public void SQLiteItemTest_RemoveBan()
|
||||
{
|
||||
//
|
||||
// TODO: Add test logic here
|
||||
//
|
||||
ItemManager manager = new ItemManager(DB);
|
||||
manager = new ItemManager(DB);
|
||||
Assert.IsNotNull(manager);
|
||||
Assert.AreEqual(2, manager.ItemBans.Count);
|
||||
manager.AddNewBan("Dirt Block");
|
||||
|
|
|
|||
|
|
@ -29,51 +29,91 @@ namespace UnitTests
|
|||
DB.Open();
|
||||
|
||||
manager = new RegionManager(DB);
|
||||
manager.ReloadForUnitTest("test");
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void AddRegion()
|
||||
{
|
||||
Region r = new Region( new Rectangle(100,100,100,100), "test", 0, "test world");
|
||||
Assert.IsTrue(manager.AddRegion(r.RegionArea.X, r.RegionArea.Y, r.RegionArea.Width, r.RegionArea.Height, r.RegionName, r.RegionWorldID));
|
||||
Region r = new Region( new Rectangle(100,100,100,100), "test", true, "test");
|
||||
Assert.IsTrue(manager.AddRegion(r.Area.X, r.Area.Y, r.Area.Width, r.Area.Height, r.Name, r.WorldID));
|
||||
Assert.AreEqual(1, manager.Regions.Count);
|
||||
Assert.IsNotNull(manager.getRegion("test"));
|
||||
|
||||
Region r2 = new Region(new Rectangle(201, 201, 100, 100), "test2", 0, "test world");
|
||||
manager.AddRegion(r2.RegionArea.X, r2.RegionArea.Y, r2.RegionArea.Width, r2.RegionArea.Height, r2.RegionName, r2.RegionWorldID);
|
||||
Region r2 = new Region(new Rectangle(201, 201, 100, 100), "test2", true, "test");
|
||||
manager.AddRegion(r2.Area.X, r2.Area.Y, r2.Area.Width, r2.Area.Height, r2.Name, r2.WorldID);
|
||||
Assert.AreEqual(2, manager.Regions.Count);
|
||||
Assert.IsNotNull(manager.getRegion("test2"));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DeleteRegion()
|
||||
{
|
||||
Assert.IsTrue(2 == manager.Regions.Count);
|
||||
Assert.IsTrue(manager.DeleteRegion("test"));
|
||||
Assert.IsTrue(1 == manager.Regions.Count);
|
||||
Assert.IsTrue(manager.DeleteRegion("test2"));
|
||||
Assert.AreEqual(0, manager.Regions.Count);
|
||||
Assert.IsTrue(0 == manager.Regions.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InRegion()
|
||||
{
|
||||
//
|
||||
// TODO: Add test logic here
|
||||
//
|
||||
Assert.IsTrue(manager.InArea(100, 100));
|
||||
Assert.IsTrue(manager.InArea(150, 150));
|
||||
Assert.IsTrue(manager.InArea(200, 200));
|
||||
Assert.IsTrue(manager.InArea(201, 201));
|
||||
Assert.IsTrue(manager.InArea(251, 251));
|
||||
Assert.IsTrue(manager.InArea(301, 301));
|
||||
Assert.IsFalse(manager.InArea(311, 311));
|
||||
Assert.IsFalse(manager.InArea(99, 99));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMethod2()
|
||||
public void SetRegionState()
|
||||
{
|
||||
//
|
||||
// TODO: Add test logic here
|
||||
//
|
||||
Assert.IsTrue(manager.getRegion("test").DisableBuild);
|
||||
manager.SetRegionStateTest("test", "test", false);
|
||||
Assert.IsTrue(!manager.getRegion("test").DisableBuild);
|
||||
manager.SetRegionStateTest("test", "test", true);
|
||||
Assert.IsTrue(manager.getRegion("test").DisableBuild);
|
||||
Assert.IsTrue(manager.getRegion("test2").DisableBuild);
|
||||
manager.SetRegionStateTest("test2", "test", false);
|
||||
Assert.IsTrue(!manager.getRegion("test2").DisableBuild);
|
||||
manager.SetRegionStateTest("test2", "test", true);
|
||||
Assert.IsTrue(manager.getRegion("test2").DisableBuild);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMethod3()
|
||||
public void CanBuild()
|
||||
{
|
||||
//
|
||||
// TODO: Add test logic here
|
||||
//
|
||||
/**
|
||||
* For now, this test is useless. Need to implement user groups so we can alter Canbuild permission.
|
||||
*/
|
||||
TSPlayer t = new TSPlayer(0);
|
||||
Assert.IsFalse( manager.CanBuild( 100,100,t) );
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AddUser()
|
||||
{
|
||||
/**
|
||||
* For now, this test is useless. Need to implement users so we have names to get ids from.
|
||||
*/
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ListID()
|
||||
{
|
||||
Assert.IsTrue(RegionManager.ListIDs("1,2,3,4,5").Count == 5);
|
||||
Assert.IsTrue(RegionManager.ListIDs("").Count == 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ListRegions()
|
||||
{
|
||||
//needs a little more work.
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<OrderedTest name="RegionManagerTest" storage="c:\users\virus\git\tshock\unittests\regionmanagertest.orderedtest" id="7601a790-d2fb-45d2-a612-1ae4de84eb61" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<OrderedTest name="regionmanagertest" storage="c:\users\virus\git\tshock\unittests\regionmanagertest.orderedtest" id="7601a790-d2fb-45d2-a612-1ae4de84eb61" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<Execution id="e2bb6bb7-7bc7-43d5-bb81-e2d13d377599" />
|
||||
<TestLinks>
|
||||
<TestLink id="8d92e80b-8c9d-7a14-5c3a-eba6790be784" name="AddRegion" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="a8d03dce-530d-a255-9115-3b783c8a973c" name="DeleteRegion" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="57686a56-2684-8c17-1564-ed9a3c37b167" name="InRegion" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="c77a874e-5605-7aec-f487-110deaa7fafb" name="TestMethod2" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="521a8e25-1f75-066f-b839-56fee4f2a1b1" name="TestMethod3" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="05a473bf-6457-6122-6150-b1aa82e8f869" name="SetRegionState" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="999dec4b-8a9b-3d06-02fb-622ecb449e82" name="CanBuild" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="80e781d1-fd68-212a-9099-8791ad55ed9f" name="AddUser" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="dc9d05c0-db88-716a-bbe0-aff585f7681d" name="ListID" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="e13e8546-b310-71c3-e068-1ecd18bfec8f" name="ListRegions" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<TestLink id="a8d03dce-530d-a255-9115-3b783c8a973c" name="DeleteRegion" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
</TestLinks>
|
||||
</OrderedTest>
|
||||
Loading…
Add table
Add a link
Reference in a new issue