public static bool Item_Save(this DB db, IGameObject item, string owner, out string msg, out SqlTransaction tran, out SqlConnection con) { /* WHEN NOT MATCHED [BY TARGET] -- row exists in source but not in target WHEN NOT MATCHED BY SOURCE -- row exists in target but not in source */ if(((ServerGameObject)item).IsTransient) { tran = null; con = null; msg = "Transient objects can't be saved."; return false; } tran = null; bool result = true; msg = ""; con = DB.GameDataConnection; SqlCommand cmd = DB.GetCommand(con, "Items_Save", true); SqlParameter pout = new SqlParameter("@resultCode", 0); pout.Direction = ParameterDirection.Output; cmd.Parameters.Add(pout); cmd.Parameters.Add(new SqlParameter("@itemID", item.UID)); cmd.Parameters.Add(new SqlParameter("@owner", owner)); cmd.Parameters.Add(new SqlParameter("@context", item.Context)); cmd.Parameters.Add(new SqlParameter("@typeHash", item.TypeHash)); cmd.Parameters.Add(new SqlParameter("@typeHash", item.TypeHash)); cmd.Parameters.Add(new SqlParameter("@stackCount", item.StackCount)); cmd.Parameters.Add(new SqlParameter("@template", item.ItemTemplate)); cmd.Parameters.Add(new SqlParameter("@objectOwner", item.Owner)); cmd.Parameters.Add(new SqlParameter("@typeHash", (long)item.TypeHash)); cmd.Parameters.Add(new SqlParameter("@createdOn", item.CreatedOn)); cmd.Parameters.Add(new SqlParameter("@got", (int)item.GameObjectType)); if (!((ServerGameObject)item).IsStatic) { Pointer dataPointer = new Pointer(); byte[] bindata = new byte[1024]; item.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)); SqlParameter ints = new SqlParameter("@intProperties", ItemIntPropertiesToTable(item.Properties.GetAllPropertiesOfKind(PropertyKind.Int32), item.UID)); ints.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(ints); SqlParameter floats = new SqlParameter("@floatProperties", ItemFloatPropertiesToTable(item.Properties.GetAllPropertiesOfKind(PropertyKind.Single), item.UID)); floats.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(floats); SqlParameter longs = new SqlParameter("@longProperties", ItemLongPropertiesToTable(item.Properties.GetAllPropertiesOfKind(PropertyKind.Int64), item.UID)); longs.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(longs); SqlParameter strings = new SqlParameter("@stringProperties", ItemStringPropertiesToTable(item.Properties.GetAllPropertiesOfKind(PropertyKind.String), item.UID)); strings.SqlDbType = SqlDbType.Structured; cmd.Parameters.Add(strings); SqlParameter statsParm = new SqlParameter("@stats", ItemStatsToTable(item.Stats.AllStats, item.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; // -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; }