public static bool UnregisterObject(Guid go) { ServerGameObject sgo = null; AllGameObjects.TryRemove(go, out sgo); return(sgo != null); }
public static bool RegisterObject(ServerGameObject go) { if(AllGameObjects.TryAdd(go.UID, go)) { GameEvents.FireEvent(GameEventType.ObjectLoaded, go, null); return true; } return false; }
public static bool RegisterObject(ServerGameObject go) { if (AllGameObjects.TryAdd(go.UID, go)) { GameEvents.FireEvent(GameEventType.ObjectLoaded, go, null); return(true); } return(false); }
/// <summary> /// Gets a reference to a server game object currently in memory, i.e. previously loaded from the DB. /// </summary> /// <param name="id">id of the object being returned</param> /// <returns></returns> public ServerGameObject GetItem(Guid id, ServerGameObjectManager gom, bool includeDeleted = false) { ServerGameObject sgo = gom.GetGameObjectFromId(id) as ServerGameObject; if (sgo == null || (!includeDeleted && sgo.IsDeleted)) { return(null); } return(sgo); }
/// <summary> /// Gets called as the Item is being created in the Database. If you have additional DB tasks /// to add, now is the time. Use the supplied connection and transaction objects. The connection should already /// be open. /// Do NOT close the connection and do NOT commit /rollback the transaction. Simply return true or false if /// you want the creation to be committed or not. /// </summary> /// <param name="ItemId">the id of the Item to delete</param> /// <param name="owner">the owner of the Item to delete</param> /// <param name="permaPurge">should the data be permanently purged</param> /// <param name="reason">reason for service log</param> /// <param name="rsltMsg">a message saying why deletion failed, if any</param> /// <param name="con">the connection object to use for additional database work in relation to Item creation</param> /// <param name="tran">the transaction object to use for additional database work in relation to Item creation</param> /// <returns>return false if you do not want the transaction to be committed, which will also cause Item creation to fail</returns> /* * public bool DeleteItem(Guid ItemId, ServerUser player, bool permaPurge, string reason, ref string rsltMsg) * { * SqlConnection con = null; * SqlTransaction tran = null; * * try * { * if (DB.Instance.Item_Delete(player.ID, ItemId, permaPurge, reason, out tran, out con)) * { * tran.Commit(); * return true; * } * else * { * if (con.State != System.Data.ConnectionState.Closed && con.State != System.Data.ConnectionState.Connecting) * { * if (tran != null) * { * tran.Rollback(); * } * } * } * } * catch (Exception exc) * { * if (con.State != System.Data.ConnectionState.Closed && con.State != System.Data.ConnectionState.Connecting) * { * if (tran != null) * { * tran.Rollback(); * } * } * return false; * } * finally * { * if (con != null) * { * con.Close(); * con.Dispose(); * con = null; * } * * if (tran != null) * { * tran.Dispose(); * tran = null; * } * } * * return false; * } */ /// <summary> /// Saves/updates the Item to the DB /// </summary> /// <param name="owner">owning account</param> /// <param name="id">the id for the Item to get</param> /// <returns></returns> public bool SaveItem(ServerGameObject item, string owner, ref string rsultMsg) { if (item == null) { return(false); } SqlConnection con = null; SqlTransaction tran = null; if (item.IsTransient) { rsultMsg = "Transient objects can't be saved."; return(false); } try { Guid cown = Guid.Empty; if (DB.Instance.Item_Save(item, owner, out rsultMsg, out tran, out con)) { tran.Commit(); } else { if (con.State != System.Data.ConnectionState.Closed && con.State != System.Data.ConnectionState.Connecting) { if (tran != null) { tran.Rollback(); } } rsultMsg = "Can't save Item. " + rsultMsg; return(false); } } catch (Exception e) { } finally { if (con != null) { con.Close(); con.Dispose(); con = null; } if (tran != null) { tran.Dispose(); tran = null; } } return(true); }
public override void RemoveGameObject(IGameObject actor) { if (actor == null) { return; } ServerGameObject sgo = actor as ServerGameObject; base.RemoveGameObject(actor); MasterObjectManager.UnregisterObject(actor.UID); if (actor is WispPlayer && OnPlayerRemoved != null) { OnPlayerRemoved(actor as WispPlayer); } }
public override void RegisterGameObject(IGameObject actor, Guid context) { if (actor == null) { return; } base.RegisterGameObject(actor, context); ServerGameObject sgo = actor as ServerGameObject; MasterObjectManager.RegisterObject(sgo); if (actor is WispPlayer && OnPlayerAdded != null) { OnPlayerAdded(actor as WispPlayer); } }
/// <summary> /// creates a Item object, but does not persist it. /// </summary> /// <param name="properties">Item properties to add</param> /// <param name="owner">the owning user</param> /// <param name="context">Any user defined context - could be a game room, an owning server, etc. GameObjectManager keeps sub-lists of games based on context ID. Use GUID.Empty for none. </param> /// <returns></returns> public ServerGameObject CreateNewItem(string itemTemplate, Guid context, ServerGameObjectManager gom, string owningServer) { ServerGameObject sgo = CreateItemShell(itemTemplate); if (sgo == null) { return(null); } sgo.IsGhost = true; // Instantiate the inner GameObject sgo.Context = context; // Add the needed bits sgo.UID = Guid.NewGuid(); sgo.CreatedOn = DateTime.UtcNow; sgo.OwningServer = owningServer; gom.RegisterGameObject(sgo, context); return(sgo); }
/// <summary> /// Delete an object from the world. /// </summary> /// <param name="id"></param> public void DeleteItem(Guid id, Guid accountDeleting, string reason, ServerGameObjectManager gom) { ServerGameObject sgo = null; if (gom != null) { GetItem(id, gom); } else { string msg = ""; sgo = LoadItem(id, true, "", ref msg, null); } if (sgo != null) { sgo.IsDeleted = true; sgo.DeleteReason = reason; sgo.AccountDeleted = accountDeleting; } }
/// <summary> /// Creates the item, based on the template, but doesn't register it with the object manager, nor does it persist it /// </summary> /// <param name="template"></param> /// <returns></returns> public ServerGameObject CreateItemShell(string template) { Template t = null; if (!Template.Templates.TryGetValue(template.ToLower(), out t)) { return(null); } uint hash = Factory.GetStableHash(t.Class); ServerGameObject sgo = Factory.Instance.CreateObject(hash) as ServerGameObject; if (sgo == null) { Log1.Logger("Server").Error("Tried to instantiate game object of type " + t.Class + ", but the Factory could not find that type. Was it registered?"); return(null); } foreach (uint script in t.Scripts) { GameObjectScript gos = GameObjectScript.GetScript(script); if (gos == null) { Log1.Logger("ObjectError").Error("Unable to instantiate GameObjectScript [" + script + "] for template [" + t.Name + "]. On game object [" + sgo.UID.ToString() + "]."); continue; } sgo.Scripts.AttachScript(gos); } sgo.Properties.UpdateWithValues(t.Properties); sgo.Stats.UpdateWithValues(t.Stats); sgo.ItemTemplate = t.Name; sgo.GameObjectType = t.GameObjectType; sgo.IsStatic = t.IsStatic; sgo.StackCount = t.StackCount; sgo.IsTransient = t.IsTransient; return(sgo); }
/// <summary> /// Read an item from the database. if @lockedBy is set to null or empty string it is assumed that you are not trying to take ownership of the loaded object and are opening it for read-only /// purposes. Setting the @lockedBy parameter to a server ID indicates that that server has ownership of the object. Objects cannot be saved except by the lock's owner. /// </summary> /// <param name="db"></param> /// <param name="item"></param> /// <param name="ItemId"></param> /// <param name="includeDeleted"></param> /// <param name="loadedBy"></param> /// <param name="tran"></param> /// <param name="con"></param> /// <returns></returns> public static bool Item_Load(this DB db, out ServerGameObject item, Guid ItemId, bool includeDeleted, string lockedBy, out SqlTransaction tran, out SqlConnection con) { tran = null; con = null; bool result = true; con = DB.GameDataConnection; SqlCommand cmd = DB.GetCommand(con, "Items_Get", true); cmd.Parameters.Add(new SqlParameter("@ItemId", ItemId)); cmd.Parameters.Add(new SqlParameter("@includeDeleted", includeDeleted)); cmd.Parameters.Add(new SqlParameter("@lockedBy", lockedBy)); SqlParameter pout = new SqlParameter("@resultCode", 0); pout.Direction = ParameterDirection.Output; cmd.Parameters.Add(pout); SqlDataReader reader = null; Guid context = Guid.Empty; item = null; try { int idColumn = 1; int valueColumn = 2; int nameColumn = 3; con.Open(); tran = con.BeginTransaction(IsolationLevel.Serializable); cmd.Connection = con; cmd.Transaction = tran; reader = cmd.ExecuteReader(); int count = 0; bool isStatic = false; if (reader.HasRows) // any items to read? { ServerGameObject loadedItem = null; if (reader.Read()) // read item data from Item Master Rable { string templateNum = reader.GetString(1); loadedItem = ItemUtil.Instance.CreateItemShell(templateNum); bool isDeleted = reader.GetByte(2) == 1; loadedItem.IsDeleted = isDeleted; // int GOT = reader.GetInt32(3); // set by template in CreateItemShell loadedItem.UID = reader.GetGuid(0); //loadedItem.ItemTemplate = templateNum; // set by template in CreateItemShell // loadedItem.GameObjectType = (GOT)GOT;// set by template in CreateItemShell loadedItem.CreatedOn = reader.GetDateTimeUtc(4); //isStatic = reader.GetByte(9) == 1; // set by template in CreateItemShell loadedItem.StackCount = reader.GetInt32(9); loadedItem.Owner = reader.GetGuid(10); if (!reader.IsDBNull(5)) { loadedItem.OwningServer = reader.GetString(5); } loadedItem.Context = reader.GetGuid(6); if (loadedItem.TypeHash != (uint)reader.GetInt64(7)) { Log1.Logger("Server").Error("Tried loading game object [" + loadedItem.UID.ToString() + "]. Type hash was inconsistent with database.)"); } if (!isStatic && !reader.IsDBNull(8)) { byte[] binData = (byte[])reader["BinData"]; // works good if there's not a ton of data loadedItem.Deserialize(binData, new Pointer()); /* long dataSize = reader.GetBytes(8, 0, null, 0, 0); byte[] buffer = new byte[1024]; var dataRemaining = dataSize; while (dataRemaining > 0) { int bytesToRead = (int)(buffer.Length < dataRemaining ? buffer.Length : dataRemaining); //fill the buffer reader.GetBytes(1, dataSize - dataRemaining, buffer, 0, bytesToRead); Util.Copy(buffer, 0, binData, (int)dataSize - (int)dataRemaining, bytesToRead); dataRemaining -= bytesToRead; } */ } } //if (!isStatic) { reader.NextResult(); // grab item properties bool attribsDone = false; while (!attribsDone) { //reader.NextResult(); count++; if (count == 5) { // Finished reading item attributes. Go on to the next item. attribsDone = true; } if (!reader.HasRows) { reader.NextResult(); continue; } IGameObject ci = loadedItem; switch (count) { case 1: // Float while (reader.Read()) { string name = reader.IsDBNull(nameColumn) ? "" : reader.GetString(nameColumn); ci.Properties.SetProperty(name, (int)reader.GetInt32(idColumn), (float)reader.GetDouble(valueColumn)); } break; case 2: // Int while (reader.Read()) { string name = reader.IsDBNull(nameColumn) ? "" : reader.GetString(nameColumn); ci.Properties.SetProperty(name, (int)reader.GetInt32(idColumn), reader.GetInt32(valueColumn)); } break; case 3: // Long while (reader.Read()) { string name = reader.IsDBNull(nameColumn) ? "" : reader.GetString(nameColumn); ci.Properties.SetProperty(name, (int)reader.GetInt32(idColumn), reader.GetInt64(valueColumn)); } break; case 4: // String while (reader.Read()) { string name = reader.IsDBNull(nameColumn) ? "" : reader.GetString(nameColumn); ci.Properties.SetProperty(name, (int)reader.GetInt32(idColumn), reader.GetString(valueColumn)); } break; case 5: // Stats //reader.NextResult(); // read past the Item id while (reader.Read()) { Stat s = new Stat(); s.StatID = reader.GetInt32(reader.GetOrdinal("StatID")); double cValue = reader.GetDouble(reader.GetOrdinal("CurrentValue")); double mValue = reader.GetDouble(reader.GetOrdinal("MaxValue")); double mnValue = reader.GetDouble(reader.GetOrdinal("MinValue")); Stat proto = StatManager.Instance[s.StatID]; if (proto == null) { Log1.Logger("Server.Stats").Error("Item_Load attempted to read stat ID [" + s.StatID + "] which was not defined in the Stats.xml config file. Stat not added to Item."); continue; } s.MinValue = (float)mnValue; s.MaxValue = (float)mValue; s.ForceValue((float)cValue); s.Description = proto.Description; s.DisplayName = proto.DisplayName; s.Group = proto.Group; ci.Stats.AddStat(s); } break; } reader.NextResult(); } // while reader has next result for item properties } // if not static item item = loadedItem; } // while reader has rows } catch (Exception e) { Log1.Logger("Server").Error("[DATABASE ERROR Item_Load] : " + e.Message); result = false; } finally { if (reader != null && !reader.IsClosed) { reader.Close(); } } return result; }
public static bool Item_Create(this DB db, ServerGameObject go, string owner, out string msg, out SqlTransaction tran, out SqlConnection con) { if(go.IsTransient) { con = null; tran = null; msg = "Transient objects can't be saved to the database."; return false; } tran = null; bool result = true; msg = ""; con = DB.GameDataConnection; SqlCommand cmd = DB.GetCommand(con, "Items_Create", true); SqlParameter pout = new SqlParameter("@resultCode", 0); pout.Direction = ParameterDirection.Output; cmd.Parameters.Add(pout); cmd.Parameters.Add(new SqlParameter("@GOT", (int)go.GameObjectType)); cmd.Parameters.Add(new SqlParameter("@UID", go.UID)); cmd.Parameters.Add(new SqlParameter("@createdOn", go.CreatedOn)); cmd.Parameters.Add(new SqlParameter("@template", go.ItemTemplate)); cmd.Parameters.Add(new SqlParameter("@owner", owner)); cmd.Parameters.Add(new SqlParameter("@context", go.Context)); cmd.Parameters.Add(new SqlParameter("@typeHash", (long)go.TypeHash)); Pointer dataPointer = new Pointer(); byte[] bindata = new byte[1024]; go.Serialize(ref bindata, dataPointer); // Combine envelope and body into final data gram byte[] trimData = new byte[dataPointer.Position]; Util.Copy(bindata, 0, trimData, trimData.Length, dataPointer.Position); cmd.Parameters.Add(new SqlParameter("@binData", trimData)); cmd.Parameters.Add(new SqlParameter("@stackCount", go.StackCount)); cmd.Parameters.Add(new SqlParameter("@isStatic", go.IsStatic)); cmd.Parameters.Add(new SqlParameter("@objectOwner", go.Owner)); if (!go.IsStatic) { SqlParameter ints = new SqlParameter("@intProperties", ItemIntPropertiesToTable(go.Properties.GetAllPropertiesOfKind(PropertyKind.Int32), go.UID)); ints.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(ints); SqlParameter floats = new SqlParameter("@floatProperties", ItemFloatPropertiesToTable(go.Properties.GetAllPropertiesOfKind(PropertyKind.Single), go.UID)); floats.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(floats); SqlParameter longs = new SqlParameter("@longProperties", ItemLongPropertiesToTable(go.Properties.GetAllPropertiesOfKind(PropertyKind.Int64), go.UID)); longs.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(longs); SqlParameter strings = new SqlParameter("@stringProperties", ItemStringPropertiesToTable(go.Properties.GetAllPropertiesOfKind(PropertyKind.String), go.UID)); strings.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(strings); SqlParameter statsParm = new SqlParameter("@stats", ItemStatsToTable(go.Stats.AllStats, go.UID)); statsParm.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(statsParm); } try { con.Open(); tran = con.BeginTransaction(IsolationLevel.ReadCommitted); cmd.Connection = con; cmd.Transaction = tran; cmd.ExecuteNonQuery(); long val = (long)cmd.Parameters[0].Value; result = val > 0; switch (val) { case -1: case 0: msg = "Server was unable to created Item."; break; case 1: msg = "Item created."; break; } // -1 = unknown error creating Item // 0 = unknown error crating Item starting stats // 1 = Item created successfully } catch (Exception e) { Log1.Logger("Server").Error("[DATABASE ERROR] : " + e.Message); result = false; } finally { /* if (con != null) { con.Close(); con.Dispose(); con = null; } * Calling method must close connection. this is to allow API users to append to the Item creation method and commit the transaction before closing the connection.*/ } return result; }
private static DataTable GameObjectToTable(ServerGameObject input, DataTable table = null) { if (table == null) { table = new DataTable("ItemTable"); table.Columns.Add("Template", typeof(string)); table.Columns.Add("CreatedOn", typeof(DateTime)); table.Columns.Add("GOT", typeof(int)); table.Columns.Add("UID", typeof(Guid)); table.Columns.Add("Owner", typeof(string)); table.Columns.Add("Context", typeof(Guid)); table.Columns.Add("TypeHash", typeof(long)); table.Columns.Add("BinData", typeof(byte[])); table.Columns.Add("IsStatic", typeof(byte)); table.Columns.Add("StackCount", typeof(int)); table.Columns.Add("ObjectOwner", typeof(Guid)); } DataRow r = table.NewRow(); r["Template"] = input.ItemTemplate; r["CreatedOn"] = input.CreatedOn; r["GOT"] = (int)input.GameObjectType; r["UID"] = input.UID; r["Owner"] = input.OwningServer; r["Context"] = input.Context; r["TypeHash"] = input.TypeHash; Pointer dataPointer = new Pointer(); byte[] bindata = new byte[1024]; input.Serialize(ref bindata, dataPointer); // Combine envelope and body into final data gram byte[] trimData = new byte[dataPointer.Position]; Util.Copy(bindata, 0, trimData, trimData.Length, dataPointer.Position); r["BinData"] = trimData; r["StackCount"] = input.StackCount; r["IsStatic"] = input.IsStatic; r["ObjectOwner"] = input.Owner; table.Rows.Add(r); return table; }
private static DataTable GameObjectToDeleteRow(ServerGameObject input, DataTable table = null) { if (table == null) { table = new DataTable("DeleteTable"); table.Columns.Add("ItemID", typeof(Guid)); table.Columns.Add("PermaPurge", typeof(bool)); table.Columns.Add("Account", typeof(Guid)); table.Columns.Add("DeleteReason", typeof(string)); } DataRow r = table.NewRow(); r["ItemID"] = input.UID; r["PermaPurge"] = false; r["Account"] = input.AccountDeleted; r["DeleteReason"] = input.DeleteReason; table.Rows.Add(r); return table; }
/// <summary> /// Loads an Item from the DB /// </summary> /// <param name="owner">owning account</param> /// <param name="id">the id for the Item to get</param> /// <returns></returns> public ServerGameObject LoadItem(Guid id, bool includeDeleted, string lockedByServerId, ref string rsultMsg, ServerGameObjectManager gom) { if (id == Guid.Empty) { return(null); } SqlConnection con = null; SqlTransaction tran = null; ServerGameObject sgo = null; if (gom != null) { sgo = gom.GetGameObjectFromId(id) as ServerGameObject; if (sgo != null) { return(sgo); } } try { Guid cown = Guid.Empty; if (DB.Instance.Item_Load(out sgo, id, includeDeleted, lockedByServerId, out tran, out con)) { ((ServerGameObject)sgo).IsDirty = false; ((ServerGameObject)sgo).IsGhost = false; tran.Commit(); bool isDeleted = false; isDeleted = ((ServerGameObject)sgo).IsDeleted; if (!isDeleted && lockedByServerId != null && lockedByServerId.Length > 0) { if (gom != null) { gom.RegisterGameObject(sgo, sgo.Context); } } } else { rsultMsg = "Item doesn't exist."; return(null); } } catch (Exception e) { return(null); } finally { if (con != null) { con.Close(); con.Dispose(); con = null; } if (tran != null) { tran.Dispose(); tran = null; } } return(sgo); }
/// <summary> /// Creates a new Item in the DB using the Item's template XML file as a basis for stats and properties. If you want to override any of the default /// properties, pass in the appropriate ItemProperties property bag. /// </summary> /// <param name="msg">an error message, if any</param> /// <returns></returns> public bool PersistNewItem(ServerGameObject ci, string owner, ref string msg) { SqlConnection con = null; SqlTransaction tran = null; if (ci != null && ci.IsTransient) { msg = "Transient objects can't be saved."; return(false); } try { if (ValidateItemCreateRequest(ci, ref msg)) { if (DB.Instance.Item_Create(ci, owner, out msg, out tran, out con)) { tran.Commit(); return(true); } else { if (con.State != System.Data.ConnectionState.Closed && con.State != System.Data.ConnectionState.Connecting) { if (tran != null) { tran.Rollback(); } } } } } catch (Exception exc) { if (con.State != System.Data.ConnectionState.Closed && con.State != System.Data.ConnectionState.Connecting) { if (tran != null) { tran.Rollback(); } } return(false); } finally { if (con != null) { con.Close(); con.Dispose(); con = null; } if (tran != null) { tran.Dispose(); tran = null; } } return(false); }