Modularise database backend even more.

This commit is contained in:
UnknownShadow200 2016-10-25 14:38:31 +11:00
parent 4d2de13262
commit a97a428c81
17 changed files with 229 additions and 184 deletions

View File

@ -46,19 +46,24 @@ namespace MCGalaxy.Commands {
//safe against SQL injections because whoTo is checked for illegal characters
Database.Backend.CreateTable("Inbox" + receiverName, createInbox);
Database.Execute("INSERT INTO `Inbox" + receiverName + "` (PlayerFrom, TimeSent, Contents) VALUES (@0, @1, @2)",
senderName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), message);
Database.Backend.AddRow("Inbox" + receiverName, "PlayerFrom, TimeSent, Contents",
senderName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), message);
Player receiver = PlayerInfo.FindExact(receiverName);
Player.Message(p, "Message sent to &5" + receiverName + ".");
if (receiver == null) return;
p.MessageTo(receiver, "Message recieved from &5" + senderName + "%S.");
if (Player.IsSuper(p)) {
receiver.SendMessage("Message recieved from &5" + senderName + "%S.");
} else {
p.MessageTo(receiver, "Message recieved from &5" + senderName + "%S.");
}
}
static ColumnParams[] createInbox = {
new ColumnParams("PlayerFrom", ColumnType.Char, 20),
new ColumnParams("TimeSent", ColumnType.DateTime),
new ColumnParams("Contents", ColumnType.VarChar, 255),
static ColumnDesc[] createInbox = {
new ColumnDesc("PlayerFrom", ColumnType.Char, 20),
new ColumnDesc("TimeSent", ColumnType.DateTime),
new ColumnDesc("Contents", ColumnType.VarChar, 255),
};
public override void Help(Player p) {

View File

@ -144,10 +144,12 @@ namespace MCGalaxy.Commands.Building {
count = Messages.Rows.Count;
}
string syntax = count == 0 ?
"INSERT INTO `Messages" + lvlName + "` (X, Y, Z, Message) VALUES (@0, @1, @2, @3)"
: "UPDATE `Messages" + lvlName + "` SET Message=@3 WHERE X=@0 AND Y=@1 AND Z=@2";
Database.Execute(syntax, x, y, z, data.Message);
if (count == 0) {
Database.Backend.AddRow("Messages" + lvlName, "X, Y, Z, Message", x, y, z, data.Message);
} else {
Database.Backend.UpdateRows("Messages" + lvlName, "Message=@3",
"WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z, data.Message);
}
}
}

View File

@ -66,7 +66,7 @@ namespace MCGalaxy.Commands.Building {
// Hardcoded aliases for backwards compatibility
id = Block.Invalid;
if (name == "") id = Block.blue_portal;
if (name == "blue") id = Block.blue_portal;
if (name == "blue") id = Block.blue_portal;
if (name == "orange") id = Block.orange_portal;
if (name == "air") id = Block.air_portal;
if (name == "water") id = Block.water_portal;
@ -122,10 +122,13 @@ namespace MCGalaxy.Commands.Building {
count = portals.Rows.Count;
}
string syntax = count == 0 ?
"INSERT INTO `Portals" + lvlName + "` (EntryX, EntryY, EntryZ, ExitX, ExitY, ExitZ, ExitMap) VALUES (@0, @1, @2, @3, @4, @5, @6)"
: "UPDATE `Portals" + lvlName + "` SET ExitMap=@6, ExitX=@3, ExitY=@4, ExitZ=@5 WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2";
Database.Execute(syntax, P.x, P.y, P.z, x, y, z, p.level.name);
if (count == 0) {
Database.Backend.AddRow("Portals" + lvlName, "EntryX, EntryY, EntryZ, ExitX, ExitY, ExitZ, ExitMap",
P.x, P.y, P.z, x, y, z, p.level.name);
} else {
Database.Backend.UpdateRows("Portals" + lvlName, "ExitMap=@6, ExitX=@3, ExitY=@4, ExitZ=@5",
"WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", P.x, P.y, P.z, x, y, z, p.level.name);
}
}
if (P.Map == p.level.name)
p.SendBlockchange(P.x, P.y, P.z, bp.Block, bp.ExtBlock);
@ -199,7 +202,7 @@ namespace MCGalaxy.Commands.Building {
BlockDefinition def = lvl.CustomBlockDefs[props.BlockId];
return def == null ? null : def.Name.Replace(" ", "");
}
public override void Help(Player p) {
Player.Message(p, "%T/portal [block]");
Player.Message(p, "%HPlace a block for the entry, then another block for exit.");
@ -209,7 +212,7 @@ namespace MCGalaxy.Commands.Building {
string blocks = Block.Props.Join(props => Format(props));
if (!Player.IsSuper(p)) {
string custom = p.level.CustomBlockProps.Join(props => FormatCustom(p.level, props));
if (blocks != "" && custom != "")
if (blocks != "" && custom != "")
blocks = blocks + ", " + custom;
}

View File

@ -78,10 +78,10 @@ namespace MCGalaxy.SQL {
Database.Execute(syntax);
}
protected override void CreateTableColumns(StringBuilder sql, ColumnParams[] columns) {
protected override void CreateTableColumns(StringBuilder sql, ColumnDesc[] columns) {
string priKey = null;
for (int i = 0; i < columns.Length; i++) {
ColumnParams col = columns[i];
ColumnDesc col = columns[i];
sql.Append(col.Column).Append(' ').Append(col.FormatType());
if (col.PrimaryKey) priKey = col.Column;
@ -98,6 +98,10 @@ namespace MCGalaxy.SQL {
sql.AppendLine();
}
}
public override void AddOrReplaceRow(string table, string columns, params object[] args) {
DoInsert("REPLACE INTO", table, columns, args);
}
}

View File

@ -73,10 +73,10 @@ namespace MCGalaxy.SQL {
Database.Execute(syntax);
}
protected override void CreateTableColumns(StringBuilder sql, ColumnParams[] columns) {
protected override void CreateTableColumns(StringBuilder sql, ColumnDesc[] columns) {
string priKey = null;
for (int i = 0; i < columns.Length; i++) {
ColumnParams col = columns[i];
ColumnDesc col = columns[i];
if (col.Type == ColumnType.Bool) {
sql.Append(col.Column).Append(' ').Append("TINYINT");
} else {
@ -102,6 +102,10 @@ namespace MCGalaxy.SQL {
sql.AppendLine();
}
}
public override void AddOrReplaceRow(string table, string columns, params object[] args) {
DoInsert("INSERT OR REPLACE INTO", table, columns, args);
}
}

View File

@ -19,23 +19,23 @@ using System;
namespace MCGalaxy.SQL {
/// <summary> Provides the description of a column for an SQL create statement. </summary>
public struct ColumnParams {
/// <summary> Describes a column for an SQL create statement. </summary>
public struct ColumnDesc {
public readonly string Column;
public readonly ColumnType Type;
public readonly ushort TextLength;
public readonly ushort MaxLength;
public readonly bool AutoIncrement;
public readonly bool PrimaryKey;
public readonly bool NotNull;
public readonly string DefaultValue;
public ColumnParams(string col, ColumnType type, ushort textLen = 0,
public ColumnDesc(string col, ColumnType type, ushort maxLen = 0,
bool autoInc = false, bool priKey = false,
bool notNull = false, string def = null) {
Column = col;
Type = type;
TextLength = textLen;
MaxLength = maxLen;
AutoIncrement = autoInc;
PrimaryKey = priKey;
NotNull = notNull;
@ -43,15 +43,16 @@ namespace MCGalaxy.SQL {
}
public string FormatType() {
if (Type == ColumnType.Char) return "CHAR(" + TextLength + ")";
if (Type == ColumnType.VarChar) return "VARCHAR(" + TextLength + ")";
if (Type == ColumnType.Char) return "CHAR(" + MaxLength + ")";
if (Type == ColumnType.VarChar) return "VARCHAR(" + MaxLength + ")";
return colTypes[(int)Type];
}
static string[] colTypes = {
"TINYINT UNSIGNED", "SMALLINT UNSIGNED", "MEDIUMINT UNSIGNED",
"INT UNSIGNED", "BIGINT UNSIGNED", "TINYINT", "SMALLINT",
"MEDIUMINT", "INT", "BIGINT", "INTEGER", "BOOL", "DATETIME", "TEXT" };
"MEDIUMINT", "INT", "BIGINT", "INTEGER", "BOOL", "DATETIME", "TEXT"
};
}
public enum ColumnType {

View File

@ -110,20 +110,24 @@ namespace MCGalaxy.SQL {
static string[] ids = null;
static void BindParams(ParameterisedQuery query, object[] args) {
if (args == null || args.Length == 0) return;
string[] names = GetParamNames(args.Length);
for (int i = 0; i < args.Length; i++)
query.AddParam(names[i], args[i]);
}
internal static string[] GetParamNames(int count) {
// Avoid allocation overhead from string concat every query by caching
string[] names = null;
lock (idsLock) {
names = ids;
if (ids == null || args.Length > ids.Length) {
ids = new string[args.Length];
for (int i = 0; i < args.Length; i++)
if (ids == null || count > ids.Length) {
ids = new string[count];
for (int i = 0; i < count; i++)
ids[i] = "@" + i;
names = ids;
}
}
for (int i = 0; i < args.Length; i++)
query.AddParam(names[i], args[i]);
return names;
}
}
}

View File

@ -23,7 +23,7 @@ namespace MCGalaxy.SQL {
public abstract class IDatabaseBackend {
/// <summary> Describes the arguments for a database connection
/// <summary> Describes the arguments for a database connection
/// (such as database name or file location) </summary>
public abstract string ConnectionString { get; }
@ -37,11 +37,11 @@ namespace MCGalaxy.SQL {
/// many sql statements as one single transaction. </summary>
public abstract BulkTransaction CreateBulk();
/// <summary> Returns a new ParameterisedQuery instance, which executes sql statements
/// <summary> Returns a new ParameterisedQuery instance, which executes sql statements
/// and manages binding of parameters for sql queries. </summary>
public abstract ParameterisedQuery CreateParameterised();
/// <summary> Returns the shared static ParamterisedQuery instance, that is only used
/// <summary> Returns the shared static ParamterisedQuery instance, that is only used
/// for sql queries with no parameters. </summary>
internal abstract ParameterisedQuery GetStaticParameterised();
@ -59,11 +59,11 @@ namespace MCGalaxy.SQL {
/// <summary> Adds a new coloumn to the given table. </summary>
/// <remarks> Note colAfter is only a hint - some database backends ignore this. </remarks>
public abstract void AddColumn(string table, string column,
public abstract void AddColumn(string table, string column,
string colType, string colAfter);
/// <summary> Creates a new table in the database (unless it already exists). </summary>
public virtual void CreateTable(string table, ColumnParams[] columns) {
public virtual void CreateTable(string table, ColumnDesc[] columns) {
StringBuilder sql = new StringBuilder();
sql.AppendLine("CREATE TABLE if not exists `" + table + "` (");
CreateTableColumns(sql, columns);
@ -71,16 +71,14 @@ namespace MCGalaxy.SQL {
Database.Execute(sql.ToString());
}
/// <summary> Creates a new table in the database (unless it already exists). </summary>
protected abstract void CreateTableColumns(StringBuilder sql, ColumnParams[] columns);
protected abstract void CreateTableColumns(StringBuilder sql, ColumnDesc[] columns);
/// <summary> Completely removes the given table from the database. </summary>
/// <summary> Completely removes the given table. </summary>
public virtual void DeleteTable(string table) {
string syntax = "DROP TABLE `" + table + "`";
Database.Execute(syntax);
}
/// <summary> Inserts/Copies all the rows from the source table into the destination table. </summary>
/// <remarks> Note: This may work incorrectly if the tables have different schema. </remarks>
public virtual void CopyAllRows(string srcTable, string dstTable) {
@ -88,31 +86,56 @@ namespace MCGalaxy.SQL {
Database.Execute(syntax);
}
/// <summary> Retrieves rows for the given table from the database. </summary>
/// <remarks> modifier is optional SQL which can be used to retrieve only certain rows,
/// <summary> Retrieves rows for the given table. </summary>
/// <remarks> modifier is optional SQL which can be used to retrieve only certain rows,
/// return rows in a certain order, etc.</remarks>
public virtual DataTable GetRows(string table, string columns,
public virtual DataTable GetRows(string table, string columns,
string modifier = "", params object[] args) {
string syntax = "SELECT " + columns + " FROM `" + table + "`";
if (modifier != "") syntax += " " + modifier;
return Database.Fill(syntax, args);
}
/// <summary> Updates rows for the given table from the database. </summary>
/// <summary> Updates rows for the given table. </summary>
/// <remarks> modifier is optional SQL which can be used to update only certain rows.</remarks>
public virtual void UpdateRows(string table, string columns,
public virtual void UpdateRows(string table, string columns,
string modifier = "", params object[] args) {
string syntax = "UPDATE `" + table + "` SET " + columns;
if (modifier != "") syntax += " " + modifier;
Database.Execute(syntax, args);
}
/// <summary> Deletes rows for the given table from the database. </summary>
/// <summary> Deletes rows for the given table. </summary>
/// <remarks> modifier is optional SQL which can be used to delete only certain rows.</remarks>
public virtual void DeleteRows(string table, string modifier = "", params object[] args) {
string syntax = "DELETE FROM `" + table + "`";
if (modifier != "") syntax += " " + modifier;
Database.Execute(syntax, args);
}
/// <summary> Adds a row to the given table. </summary>
public virtual void AddRow(string table, string columns, params object[] args) {
DoInsert("INSERT INTO", table, columns, args);
}
/// <summary> Adds or replaces a row (same primary key) in the given table. </summary>
public abstract void AddOrReplaceRow(string table, string columns, params object[] args);
protected void DoInsert(string command, string table,
string columns, params object[] args) {
StringBuilder sql = new StringBuilder(command);
sql.Append(" `").Append(table).Append("` ");
sql.Append('(').Append(columns).Append(')');
string[] names = Database.GetParamNames(args.Length);
sql.Append(" VALUES (");
for (int i = 0; i < args.Length; i++) {
sql.Append(names[i]);
if (i < args.Length - 1) sql.Append(", ");
else sql.Append(")");
}
Database.Execute(sql.ToString(), args);
}
}
}

View File

@ -14,7 +14,7 @@
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
*/
using System;
using System.Collections.Generic;
using System.Data;
@ -27,24 +27,24 @@ using MCGalaxy.SQL;
namespace MCGalaxy {
public static class Economy {
public static bool Enabled;
public static bool Enabled;
const string propertiesFile = "properties/economy.properties";
static ColumnParams[] createEconomy = {
new ColumnParams("player", ColumnType.VarChar, 20, priKey: true),
new ColumnParams("money", ColumnType.Int32),
new ColumnParams("total", ColumnType.Integer, notNull: true, def: "0"),
new ColumnParams("purchase", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
new ColumnParams("payment", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
new ColumnParams("salary", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
new ColumnParams("fine", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
static ColumnDesc[] createEconomy = {
new ColumnDesc("player", ColumnType.VarChar, 20, priKey: true),
new ColumnDesc("money", ColumnType.Int32),
new ColumnDesc("total", ColumnType.Integer, notNull: true, def: "0"),
new ColumnDesc("purchase", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
new ColumnDesc("payment", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
new ColumnDesc("salary", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
new ColumnDesc("fine", ColumnType.VarChar, 255, notNull: true, def: "'%cNone'"),
};
public struct EcoStats {
public string Player, Purchase, Payment, Salary, Fine;
public int TotalSpent;
public EcoStats(int tot, string player, string pur,
public EcoStats(int tot, string player, string pur,
string pay, string sal, string fin) {
TotalSpent = tot;
Player = player;
@ -77,9 +77,9 @@ namespace MCGalaxy {
}
public static void Load() {
if (!File.Exists(propertiesFile)) {
Server.s.Log("Economy properties don't exist, creating");
Save();
if (!File.Exists(propertiesFile)) {
Server.s.Log("Economy properties don't exist, creating");
Save();
}
using (StreamReader r = new StreamReader(propertiesFile)) {
@ -123,10 +123,9 @@ namespace MCGalaxy {
}
public static void UpdateStats(EcoStats stats) {
string type = Server.useMySQL ? "REPLACE INTO" : "INSERT OR REPLACE INTO";
Database.Execute(type + " Economy (player, money, total, purchase, payment, salary, fine) " +
"VALUES (@0, @1, @2, @3, @4, @5, @6)", stats.Player, 0, stats.TotalSpent,
stats.Purchase, stats.Payment, stats.Salary, stats.Fine);
Database.Backend.AddOrReplaceRow("Economy", "player, money, total, purchase, payment, salary, fine",
stats.Player, 0, stats.TotalSpent, stats.Purchase,
stats.Payment, stats.Salary, stats.Fine);
}
public static EcoStats RetrieveStats(string name) {
@ -157,13 +156,13 @@ namespace MCGalaxy {
}
public static void UpdateMoney(string name, int money) {
Database.Backend.UpdateRows("Players", "Money = @1",
Database.Backend.UpdateRows("Players", "Money = @1",
"WHERE Name = @0", name, money);
}
public static List<Item> Items = new List<Item>() { new ColorItem(), new TitleColorItem(),
new TitleItem(), new RankItem(), new LevelItem(), new LoginMessageItem(),
new LogoutMessageItem(), new BlocksItem(), new QueueLevelItem(),
new TitleItem(), new RankItem(), new LevelItem(), new LoginMessageItem(),
new LogoutMessageItem(), new BlocksItem(), new QueueLevelItem(),
new InfectMessageItem(), new NickItem(), new ReviveItem(),
new HumanInvisibilityItem(), new ZombieInvisibilityItem() };
@ -177,7 +176,7 @@ namespace MCGalaxy {
}
return null;
}
public static string GetItemNames() {
string items = Items.Join(x => x.Enabled ? x.ShopName : null);
return items.Length == 0 ? "(no enabled items)" : items;
@ -189,7 +188,7 @@ namespace MCGalaxy {
public static RankItem Ranks { get { return (RankItem)Items[3]; } }
public static LevelItem Levels { get { return (LevelItem)Items[4]; } }
public static void MakePurchase(Player p, int cost, string item) {
public static void MakePurchase(Player p, int cost, string item) {
p.SetMoney(p.money - cost);
Player.Message(p, "Your balance is now &f{0} &3{1}", p.money, Server.moneys);
@ -197,7 +196,7 @@ namespace MCGalaxy {
stats.TotalSpent += cost;
stats.Purchase = item + "%3 for %f" + cost + " %3" + Server.moneys +
" on %f" + DateTime.Now.ToString(CultureInfo.InvariantCulture);
Economy.UpdateStats(stats);
Economy.UpdateStats(stats);
}
}
}

View File

@ -226,12 +226,12 @@ namespace MCGalaxy.Games {
}
}
static ColumnParams[] createSyntax = {
new ColumnParams("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnParams("Name", ColumnType.VarChar, 20),
new ColumnParams("Points", ColumnType.UInt24),
new ColumnParams("Captures", ColumnType.UInt24),
new ColumnParams("tags", ColumnType.UInt24),
static ColumnDesc[] createSyntax = {
new ColumnDesc("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnDesc("Name", ColumnType.VarChar, 20),
new ColumnDesc("Points", ColumnType.UInt24),
new ColumnDesc("Captures", ColumnType.UInt24),
new ColumnDesc("tags", ColumnType.UInt24),
};
/// <summary> Start the CTF game </summary>

View File

@ -249,18 +249,18 @@ namespace MCGalaxy.Games {
#region Database
static ColumnParams[] createSyntax = {
new ColumnParams("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnParams("Name", ColumnType.Char, 20),
new ColumnParams("TotalRounds", ColumnType.Int32),
new ColumnParams("MaxRounds", ColumnType.Int32),
new ColumnParams("TotalInfected", ColumnType.Int32),
new ColumnParams("MaxInfected", ColumnType.Int32),
static ColumnDesc[] createSyntax = {
new ColumnDesc("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnDesc("Name", ColumnType.Char, 20),
new ColumnDesc("TotalRounds", ColumnType.Int32),
new ColumnDesc("MaxRounds", ColumnType.Int32),
new ColumnDesc("TotalInfected", ColumnType.Int32),
new ColumnDesc("MaxInfected", ColumnType.Int32),
// reserve space for possible future additions
new ColumnParams("Additional1", ColumnType.Int32),
new ColumnParams("Additional2", ColumnType.Int32),
new ColumnParams("Additional3", ColumnType.Int32),
new ColumnParams("Additional4", ColumnType.Int32),
new ColumnDesc("Additional1", ColumnType.Int32),
new ColumnDesc("Additional2", ColumnType.Int32),
new ColumnDesc("Additional3", ColumnType.Int32),
new ColumnDesc("Additional4", ColumnType.Int32),
};
public void CheckTableExists() {
@ -284,14 +284,20 @@ namespace MCGalaxy.Games {
public void SaveZombieStats(Player p) {
if (p.Game.TotalRoundsSurvived == 0 && p.Game.TotalInfected == 0) return;
DataTable table = Database.Backend.GetRows("ZombieStats", "*", "WHERE Name=@0", p.name);
int count = 0;
using (DataTable table = Database.Backend.GetRows("ZombieStats", "*", "WHERE Name=@0", p.name)) {
count = table.Rows.Count;
}
string syntax = table.Rows.Count == 0 ?
"INSERT INTO ZombieStats (TotalRounds, MaxRounds, TotalInfected, MaxInfected, Name) VALUES (@0, @1, @2, @3, @4)"
: "UPDATE ZombieStats SET TotalRounds=@0, MaxRounds=@1, TotalInfected=@2, MaxInfected=@3 WHERE Name=@4";
Database.Execute(syntax, p.Game.TotalRoundsSurvived, p.Game.MaxRoundsSurvived,
p.Game.TotalInfected, p.Game.MaxInfected, p.name);
table.Dispose();
if (count == 0) {
Database.Backend.AddRow("ZombieStats", "TotalRounds, MaxRounds, TotalInfected, MaxInfected, Name",
p.Game.TotalRoundsSurvived, p.Game.MaxRoundsSurvived,
p.Game.TotalInfected, p.Game.MaxInfected, p.name);
} else {
Database.Backend.UpdateRows("ZombieStats", "TotalRounds=@0, MaxRounds=@1, TotalInfected=@2, MaxInfected=@3",
"WHERE Name=@4", p.Game.TotalRoundsSurvived, p.Game.MaxRoundsSurvived,
p.Game.TotalInfected, p.Game.MaxInfected, p.name);
}
}
#endregion
}

View File

@ -42,19 +42,19 @@ namespace MCGalaxy {
unsafe static bool DoSaveChanges(List<Level.BlockPos> tempCache, char* ptr,
Level lvl, string date, BulkTransaction transaction) {
string template = "INSERT INTO `Block" + lvl.name +
"` (Username, TimePerformed, X, Y, Z, type, deleted) VALUES (@Name, @Time, @X, @Y, @Z, @Tile, @Del)";
"` (Username, TimePerformed, X, Y, Z, type, deleted) VALUES (@0, @1, @2, @3, @4, @5, @6)";
ushort x, y, z;
IDbCommand cmd = BulkTransaction.CreateCommand(template, transaction);
if (cmd == null) return false;
IDataParameter nameP = transaction.CreateParam("@Name", DbType.AnsiStringFixedLength); cmd.Parameters.Add(nameP);
IDataParameter timeP = transaction.CreateParam("@Time", DbType.AnsiStringFixedLength); cmd.Parameters.Add(timeP);
IDataParameter xP = transaction.CreateParam("@X", DbType.UInt16); cmd.Parameters.Add(xP);
IDataParameter yP = transaction.CreateParam("@Y", DbType.UInt16); cmd.Parameters.Add(yP);
IDataParameter zP = transaction.CreateParam("@Z", DbType.UInt16); cmd.Parameters.Add(zP);
IDataParameter tileP = transaction.CreateParam("@Tile", DbType.Byte); cmd.Parameters.Add(tileP);
IDataParameter delP = transaction.CreateParam("@Del", DbType.Byte); cmd.Parameters.Add(delP);
IDataParameter nameP = transaction.CreateParam("@0", DbType.AnsiStringFixedLength); cmd.Parameters.Add(nameP);
IDataParameter timeP = transaction.CreateParam("@1", DbType.AnsiStringFixedLength); cmd.Parameters.Add(timeP);
IDataParameter xP = transaction.CreateParam("@2", DbType.UInt16); cmd.Parameters.Add(xP);
IDataParameter yP = transaction.CreateParam("@3", DbType.UInt16); cmd.Parameters.Add(yP);
IDataParameter zP = transaction.CreateParam("@4", DbType.UInt16); cmd.Parameters.Add(zP);
IDataParameter tileP = transaction.CreateParam("@5", DbType.Byte); cmd.Parameters.Add(tileP);
IDataParameter delP = transaction.CreateParam("@6", DbType.Byte); cmd.Parameters.Add(delP);
for (int i = 0; i < tempCache.Count; i++) {
Level.BlockPos bP = tempCache[i];
@ -165,48 +165,47 @@ namespace MCGalaxy {
object locker = ThreadSafeCache.DBCache.Get(level);
lock (locker) {
Database.Backend.CreateTable("Zone" + level, LevelDB.createZones);
Database.Execute("INSERT INTO `Zone" + level + "` (Owner, SmallX, SmallY, " +
"SmallZ, BigX, BigY, BigZ) VALUES (@0, @1, @2, @3, @4, @5, @6)",
zn.Owner, zn.smallX, zn.smallY, zn.smallZ, zn.bigX, zn.bigY, zn.bigZ);
Database.Backend.AddRow("Zone" + level, "Owner, SmallX, SmallY, SmallZ, BigX, BigY, BigZ",
zn.Owner, zn.smallX, zn.smallY, zn.smallZ, zn.bigX, zn.bigY, zn.bigZ);
}
}
internal static ColumnParams[] createBlock = {
new ColumnParams("Username", ColumnType.Char, 20),
new ColumnParams("TimePerformed", ColumnType.DateTime),
new ColumnParams("X", ColumnType.UInt16),
new ColumnParams("Y", ColumnType.UInt16),
new ColumnParams("Z", ColumnType.UInt16),
new ColumnParams("Type", ColumnType.UInt8),
new ColumnParams("Deleted", ColumnType.Bool),
internal static ColumnDesc[] createBlock = {
new ColumnDesc("Username", ColumnType.Char, 20),
new ColumnDesc("TimePerformed", ColumnType.DateTime),
new ColumnDesc("X", ColumnType.UInt16),
new ColumnDesc("Y", ColumnType.UInt16),
new ColumnDesc("Z", ColumnType.UInt16),
new ColumnDesc("Type", ColumnType.UInt8),
new ColumnDesc("Deleted", ColumnType.Bool),
};
internal static ColumnParams[] createPortals = {
new ColumnParams("EntryX", ColumnType.UInt16),
new ColumnParams("EntryY", ColumnType.UInt16),
new ColumnParams("EntryZ", ColumnType.UInt16),
new ColumnParams("ExitMap", ColumnType.Char, 20),
new ColumnParams("ExitX", ColumnType.UInt16),
new ColumnParams("ExitY", ColumnType.UInt16),
new ColumnParams("ExitZ", ColumnType.UInt16),
internal static ColumnDesc[] createPortals = {
new ColumnDesc("EntryX", ColumnType.UInt16),
new ColumnDesc("EntryY", ColumnType.UInt16),
new ColumnDesc("EntryZ", ColumnType.UInt16),
new ColumnDesc("ExitMap", ColumnType.Char, 20),
new ColumnDesc("ExitX", ColumnType.UInt16),
new ColumnDesc("ExitY", ColumnType.UInt16),
new ColumnDesc("ExitZ", ColumnType.UInt16),
};
internal static ColumnParams[] createMessages = {
new ColumnParams("X", ColumnType.UInt16),
new ColumnParams("Y", ColumnType.UInt16),
new ColumnParams("Z", ColumnType.UInt16),
new ColumnParams("Message", ColumnType.Char, 255),
internal static ColumnDesc[] createMessages = {
new ColumnDesc("X", ColumnType.UInt16),
new ColumnDesc("Y", ColumnType.UInt16),
new ColumnDesc("Z", ColumnType.UInt16),
new ColumnDesc("Message", ColumnType.Char, 255),
};
internal static ColumnParams[] createZones = {
new ColumnParams("SmallX", ColumnType.UInt16),
new ColumnParams("SmallY", ColumnType.UInt16),
new ColumnParams("SmallZ", ColumnType.UInt16),
new ColumnParams("BigX", ColumnType.UInt16),
new ColumnParams("BigY", ColumnType.UInt16),
new ColumnParams("BigZ", ColumnType.UInt16),
new ColumnParams("Owner", ColumnType.VarChar, 20),
internal static ColumnDesc[] createZones = {
new ColumnDesc("SmallX", ColumnType.UInt16),
new ColumnDesc("SmallY", ColumnType.UInt16),
new ColumnDesc("SmallZ", ColumnType.UInt16),
new ColumnDesc("BigX", ColumnType.UInt16),
new ColumnDesc("BigY", ColumnType.UInt16),
new ColumnDesc("BigZ", ColumnType.UInt16),
new ColumnDesc("Owner", ColumnType.VarChar, 20),
};
}
}

View File

@ -406,7 +406,7 @@
<Compile Include="CorePlugin\ConnectHandler.cs" />
<Compile Include="Database\Backends\SQLite.cs" />
<Compile Include="Database\BlockDB.cs" />
<Compile Include="Database\ColumnParams.cs" />
<Compile Include="Database\ColumnDesc.cs" />
<Compile Include="Database\IDatabaseBackend.cs" />
<Compile Include="Database\Backends\MySQL.cs" />
<Compile Include="Database\ParameterisedQuery.cs" />

View File

@ -748,8 +748,8 @@ namespace MCGalaxy {
try { //opstats patch (since 5.5.11)
if (Server.opstats.Contains(cmd) || (cmd == "review" && message.ToLower() == "next" && Server.reviewlist.Count > 0)) {
Database.Execute("INSERT INTO Opstats (Time, Name, Cmd, Cmdmsg) VALUES (@0, @1, @2, @3)",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), name, cmd, message);
Database.Backend.AddRow("Opstats", "Time, Name, Cmd, Cmdmsg",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), name, cmd, message);
}
} catch { }

View File

@ -106,18 +106,17 @@ namespace MCGalaxy {
}
public void save() {
const string query = "UPDATE Players SET IP=@0, LastLogin=@1, totalLogin=@2, totalDeaths=@3, " +
"Money=@4, totalBlocks=@5, totalCuboided=@6, totalKicked=@7, TimeSpent=@8 WHERE Name=@9";
if (MySQLSave != null) MySQLSave(this, query);
OnMySQLSaveEvent.Call(this, query);
if (MySQLSave != null) MySQLSave(this, "");
OnMySQLSaveEvent.Call(this, "");
if (cancelmysql) { cancelmysql = false; return; }
long blocks = PlayerData.BlocksPacked(TotalPlaced, overallBlocks);
long cuboided = PlayerData.CuboidPacked(TotalDeleted, TotalDrawn);
Database.Execute(query, ip, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
totalLogins, overallDeath, money, blocks,
cuboided, totalKicked, time.ToDBTime(), name);
long cuboided = PlayerData.CuboidPacked(TotalDeleted, TotalDrawn);
Database.Backend.UpdateRows("Players", "IP=@0, LastLogin=@1, totalLogin=@2, totalDeaths=@3, Money=@4, " +
"totalBlocks=@5, totalCuboided=@6, totalKicked=@7, TimeSpent=@8", "WHERE Name=@9",
ip, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
totalLogins, overallDeath, money, blocks,
cuboided, totalKicked, time.ToDBTime(), name);
Server.zombie.SaveZombieStats(this);
SaveUndo(this);

View File

@ -42,10 +42,9 @@ namespace MCGalaxy {
p.TotalDrawn = 0;
string now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
const string query = "INSERT INTO Players (Name, IP, FirstLogin, LastLogin, totalLogin, Title, totalDeaths" +
", Money, totalBlocks, totalKicked, TimeSpent) VALUES (@0, @1, @2, @2, @3, @4, @5, @5, @5, @5, @6)";
Database.Execute(query,
p.name, p.ip, now, 1, "", 0, p.time.ToDBTime());
Database.Backend.AddRow("Players", "Name, IP, FirstLogin, LastLogin, totalLogin, Title, " +
"totalDeaths, Money, totalBlocks, totalKicked, TimeSpent",
p.name, p.ip, now, now, 1, "", 0, 0, 0, 0, p.time.ToDBTime());
}
internal static void Load(DataTable playerDb, Player p) {

View File

@ -23,36 +23,32 @@ using MCGalaxy.SQL;
namespace MCGalaxy {
public sealed partial class Server {
static ColumnParams[] createPlayers = {
new ColumnParams("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnParams("Name", ColumnType.Text),
new ColumnParams("IP", ColumnType.Char, 15),
new ColumnParams("FirstLogin", ColumnType.DateTime),
new ColumnParams("LastLogin", ColumnType.DateTime),
new ColumnParams("totalLogin", ColumnType.Int24),
new ColumnParams("Title", ColumnType.Char, 20),
new ColumnParams("TotalDeaths", ColumnType.Int16),
new ColumnParams("Money", ColumnType.UInt24),
new ColumnParams("totalBlocks", ColumnType.Int64),
new ColumnParams("totalCuboided", ColumnType.Int64),
new ColumnParams("totalKicked", ColumnType.Int24),
new ColumnParams("TimeSpent", ColumnType.VarChar, 20),
new ColumnParams("color", ColumnType.VarChar, 6),
new ColumnParams("title_color", ColumnType.VarChar, 6),
static ColumnDesc[] createPlayers = {
new ColumnDesc("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnDesc("Name", ColumnType.Text),
new ColumnDesc("IP", ColumnType.Char, 15),
new ColumnDesc("FirstLogin", ColumnType.DateTime),
new ColumnDesc("LastLogin", ColumnType.DateTime),
new ColumnDesc("totalLogin", ColumnType.Int24),
new ColumnDesc("Title", ColumnType.Char, 20),
new ColumnDesc("TotalDeaths", ColumnType.Int16),
new ColumnDesc("Money", ColumnType.UInt24),
new ColumnDesc("totalBlocks", ColumnType.Int64),
new ColumnDesc("totalCuboided", ColumnType.Int64),
new ColumnDesc("totalKicked", ColumnType.Int24),
new ColumnDesc("TimeSpent", ColumnType.VarChar, 20),
new ColumnDesc("color", ColumnType.VarChar, 6),
new ColumnDesc("title_color", ColumnType.VarChar, 6),
};
static ColumnParams[] createOpstats = {
new ColumnParams("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnParams("Time", ColumnType.DateTime),
new ColumnParams("Name", ColumnType.Text),
new ColumnParams("Cmd", ColumnType.VarChar, 40),
new ColumnParams("Cmdmsg", ColumnType.VarChar, 40),
static ColumnDesc[] createOpstats = {
new ColumnDesc("ID", ColumnType.Integer, priKey: true, autoInc: true, notNull: true),
new ColumnDesc("Time", ColumnType.DateTime),
new ColumnDesc("Name", ColumnType.Text),
new ColumnDesc("Cmd", ColumnType.VarChar, 40),
new ColumnDesc("Cmdmsg", ColumnType.VarChar, 40),
};
const string insertSyntax =
@"INSERT INTO Opstats (Time, Name, Cmd, Cmdmsg)
SELECT Time, Name, Cmd, Cmdmsg FROM Playercmds WHERE {0};";
void InitDatabase() {
try {
Database.Backend.CreateDatabase();
@ -73,9 +69,10 @@ SELECT Time, Name, Cmd, Cmdmsg FROM Playercmds WHERE {0};";
//since 5.5.11 we are cleaning up the table Playercmds
//if Playercmds exists copy-filter to Opstats and remove Playercmds
if (Database.TableExists("Playercmds")) {
const string sql = "INSERT INTO Opstats (Time, Name, Cmd, Cmdmsg) SELECT Time, Name, Cmd, Cmdmsg FROM Playercmds WHERE {0};";
foreach (string cmd in Server.Opstats)
Database.Execute(string.Format(insertSyntax, "cmd = '" + cmd + "'"));
Database.Execute(string.Format(insertSyntax, "cmd = 'review' AND cmdmsg = 'next'"));
Database.Execute(string.Format(sql, "cmd = '" + cmd + "'"));
Database.Execute(string.Format(sql, "cmd = 'review' AND cmdmsg = 'next'"));
Database.Backend.DeleteTable("Playercmds");
}