public void UpdateWithValues(StatBag statsToUpdate) { if (statsToUpdate == null) { return; } Stat[] stats = statsToUpdate.AllStats; for (int i = 0; i < stats.Length; i++) { Stat cloneStat = new Stat(stats[i].StatID, stats[i].DisplayName, stats[i].Description, stats[i].Group, stats[i].CurrentValue, stats[i].MinValue, stats[i].MaxValue); cloneStat.Owner = this; AddStat(cloneStat); } }
/// <summary> /// Reads the Stats.xml file and returns a list of Stat definitions that it contains /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static bool Stats_LoadDefinitions(string filePath, List<Stat> stats) { XPathDocument doc = LoadDocument(filePath, true); XPathNavigator nav = null; string curStat = ""; try { if (doc == null) { return false; } nav = doc.CreateNavigator(); XPathNodeIterator iter = nav.Select(@"//Stats/*"); while (iter.MoveNext()) { string id = iter.Current.GetAttribute("StatID", ""); curStat = id; if (id == null || id.Length < 1) { Log.LogMsg("Error reading ID attribute in node " + iter.Current.InnerXml); continue; } string desc = iter.Current.GetAttribute("Desc", ""); if (desc == null) { desc = ""; } string group = iter.Current.GetAttribute("Group", ""); if (group == null) { group = ""; } string name = iter.Current.GetAttribute("Name", ""); if (name == null) { name = ""; } string minValue = iter.Current.GetAttribute("MinValue", ""); if (minValue == null) { minValue = ""; } string maxValue = iter.Current.GetAttribute("MaxValue", ""); if (maxValue == null) { maxValue = ""; } string startValue = iter.Current.GetAttribute("StartValue", ""); if (startValue == null || startValue.Length < 1) { startValue = "0"; } try { if (name.Length < 1) { throw new ArgumentException("Stat name can't be blank."); } int propertyTypeID = int.Parse(id); float fminValue = float.Parse(minValue); float fmaxValue = float.Parse(maxValue); float fstartValue = float.Parse(startValue); Stat s = new Stat(propertyTypeID, name, desc, group, fstartValue, fminValue, fmaxValue); stats.Add(s); } catch (Exception e) { Log.LogMsg("Error parsing stat data for [" + curStat + "]. [" + e.Message + "]"); } } } catch (Exception e) { Log.LogMsg("Exception thrown reading Stat definition. " + e.Message); return false; } return true; }
public static void AddStat(ref byte[] dat, Pointer curPointer, Stat stat, bool withInfoText) { AddInt(ref dat, curPointer, (int)stat.StatID); AddSingle(ref dat, curPointer, (float)stat.CurrentValue); AddSingle(ref dat, curPointer, (float)stat.MinValue); AddSingle(ref dat, curPointer, (float)stat.MaxValue); if (withInfoText) { AddString(ref dat, curPointer, stat.DisplayName); AddString(ref dat, curPointer, stat.Description); AddString(ref dat, curPointer, stat.Group); } }
public void SetStatValue(int statId, float val, float maxVal, List<string> msgs) { Stat stat = GetStat(statId); if (stat == null) { Stat newSTat = new Stat(statId, "", "", "", val, float.MinValue, float.MaxValue); newSTat.Owner = this; AddStat(newSTat); return; } if (stat.CurrentValue != val || stat.MaxValue != maxVal) { stat.SetValue(val, msgs); stat.MaxValue = maxVal; NotifyStatUpdated(stat); } }
public static bool Item_UpdateStat(this DB db, Guid ItemId, int statId, float minValue, float maxValue, float curValue) { bool rslt = true; SqlConnection con = DB.GameDataConnection; SqlCommand cmd = DB.GetCommand(con, "Items_UpdateOrInsertStats", true); cmd.Parameters.Add(new SqlParameter("@itemID", ItemId)); Stat stat = new Stat(statId, "", "", "", curValue, minValue, maxValue); List<Stat> stats = new List<Stat>(); stats.Add(stat); cmd.Parameters.Add(new SqlParameter("@InputTable", ItemStatsToTable(stats, ItemId))); try { con.Open(); int code = cmd.ExecuteNonQuery(); } catch (Exception e) { Log1.Logger("Server").Error("[DATABASE ERROR] : " + e.Message); int x = 0; rslt = false; } finally { if (con != null) { con.Close(); } } return rslt; }
public void OnStatRemoved(Guid bag, Stat p) { }
/// <summary> /// Adds a stat object to the stat bag /// </summary> /// <param name="objStat">the stat to add</param> public void AddStat(Stat objStat) { Stat current = GetStat(objStat.StatID); bool wasAdded = current == null; if (current != null) { if (m_HashedProperties != null) { m_HashedProperties.Remove(objStat.StatID); } else { Stat cur = m_LinkedProperties.FirstOrDefault(s => s.StatID == objStat.StatID); if (cur != null) { m_LinkedProperties.Remove(cur); } } } int propCount = StatCount; if (propCount + 1 > StatBag.SmallSizeLimit && m_UsingLinkedStorage) { m_UsingLinkedStorage = false; // time to switch to hashtable lookups. move the data over m_HashedProperties = new Dictionary<int, Stat>(); LinkedList<Stat>.Enumerator enu = m_LinkedProperties.GetEnumerator(); while (enu.MoveNext()) { m_HashedProperties.Add(enu.Current.StatID, enu.Current); } m_LinkedProperties.Clear(); m_LinkedProperties = null; } if (m_UsingLinkedStorage) { m_LinkedProperties.AddLast(objStat); } else { m_HashedProperties.Add(objStat.StatID, objStat); } objStat.Owner = this; if (wasAdded) { NotifyStatAdded(objStat); } else { NotifyStatUpdated(objStat); } }
public Stat Copy() { Stat s = new Stat(); s.StatID = this.StatID; s.DisplayName = this.DisplayName; s.Description = this.Description; s.Group = this.Group; s.CurrentValue = this.CurrentValue; s.MinValue = this.MinValue; s.MaxValue = this.MaxValue; return s; }
public void OnStatUpdated(Guid bag, Stat s) { IsDirty = true; }
public static bool LoadTemplate(XPathDocument docNav) { Template t = new Template(); bool isValidTemplate = false; try { // Create a navigator to query with XPath. XPathNavigator nav = docNav.CreateNavigator(); XPathNavigator root = nav.SelectSingleNode("//Item"); t.Description = root.GetAttribute("Name", ""); t.Class = root.GetAttribute("Class", ""); bool isStatic = true; if (!bool.TryParse(root.GetAttribute("IsStatic", ""), out isStatic)) { isStatic = true; // default to static item } t.IsStatic = isStatic; bool isTransient = true; if (!bool.TryParse(root.GetAttribute("IsTransient", ""), out isTransient)) { isTransient = true; // default to Transient, non-persisting item } t.IsTransient = isTransient; int stackCount = 1; if (!int.TryParse(root.GetAttribute("StackCount", ""), out stackCount)) { stackCount = 1; // default to Transient, non-persisting item } t.StackCount = stackCount; if (t.Class.Length < 1) { Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [Class (fully qualified type name) could not be determined. Make sure that the Class attribute is defined.]"); goto bailout; } GOT got = GOT.None; string gotStr = root.GetAttribute("GOT", ""); try { got = (GOT)Enum.Parse(typeof(GOT), gotStr); } catch { } if (got == GOT.None) { Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [GOT (Game object type) could not be determined. Make sure that GOT value exists in GOT enum cs file.]"); goto bailout; } t.GameObjectType = got; string strExpression = "//Item/Properties/*"; XPathNodeIterator NodeIter = nav.Select(strExpression); //Iterate through the results showing the element value. while (NodeIter.MoveNext()) { string name = NodeIter.Current.GetAttribute("Name", ""); if (name.Length < 1) { Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [Property Name attribute is missing.]"); goto bailout; } string stringValue = NodeIter.Current.GetAttribute("StringValue", ""); string intValue = NodeIter.Current.GetAttribute("IntValue", ""); string floatValue = NodeIter.Current.GetAttribute("FloatValue", ""); string longValue = NodeIter.Current.GetAttribute("LongValue", ""); if (stringValue.Length < 1 && intValue.Length < 1 && floatValue.Length < 1 && longValue.Length < 1) { Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [Must set either StringValue, IntValue, FloatValue or LongValue for property " + name + ".]"); goto bailout; } if (stringValue.Length > 0) { t.Properties.SetProperty(name, stringValue); } else if (floatValue.Length > 1) { try { float val = float.Parse(floatValue); t.Properties.SetProperty(name, val); } catch { Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [Must specify a valid number for FloatValue for property " + name + ".]"); goto bailout; } } else if (intValue.Length > 0) { try { int val = int.Parse(intValue); t.Properties.SetProperty(name, val); } catch { Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [Must specify a valid number for IntValue for property " + name + ".]"); goto bailout; } } else if (longValue.Length > 0) { try { long val = long.Parse(longValue); t.Properties.SetProperty(name, val); } catch { Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [Must specify a valid number for LongValue for property " + name + ".]"); goto bailout; } } } strExpression = "//Item/Stats/*"; NodeIter = nav.Select(strExpression); //Iterate through the results showing the element value. while (NodeIter.MoveNext()) { string id = NodeIter.Current.GetAttribute("StatID", ""); string value = NodeIter.Current.GetAttribute("StartValue", ""); if (value.Length < 1) { value = "0"; } float val = float.Parse(value); Stat prototype = StatManager.Instance.AllStats.GetStat(id); if (prototype == null) { Log.LogMsg("Failed to load stat [" + id + "] for template [" + t.Description + "]. Make sure stat is defiend in Stats.xml."); continue; } Stat ns = new Stat( prototype.StatID, prototype.DisplayName, prototype.Description, prototype.Group, prototype.CurrentValue, prototype.MinValue, prototype.MaxValue); ns.ForceValue(val); t.Stats.AddStat(ns); } strExpression = "//Item/Scripts/*"; NodeIter = nav.Select(strExpression); //Iterate through the results showing the element value. while (NodeIter.MoveNext()) { string name = NodeIter.Current.GetAttribute("Name", ""); if(!name.StartsWith("Scripts.")) { name = "Scripts." + name; } if (name.Length > 0) { GameObjectScript s = GameObjectScript.GetScript(Factory.GetStableHash(name)); if (s == null) { Log.LogMsg("Unable to instantiate script [" + name + "] on template [" + docNav.ToString() + "]. Factory couldn't create script. Was it registered using Factor.Register()?"); } else { t.Scripts.Add(Factory.GetStableHash(name)); } } } isValidTemplate = true; } catch (Exception e) { isValidTemplate = false; Log.LogMsg("Failed to load template [" + docNav.ToString() + "] - [" + e.Message + "]"); } bailout: if (isValidTemplate) { t.Name = t.Description.ToLower();// Path.GetFileNameWithoutExtension(template).ToLower(); Templates.Add(t.Name, t); //Log1.Logger("Server").Info("Loaded template [" + Path.GetFileNameWithoutExtension(template) + "]"); } else { Log.LogMsg("Failed to load template [" + docNav.ToString() + "]"); } return isValidTemplate; }
public void OnStatRemoved(Guid bag, Stat p) { IsDirty = true; }
public void OnStatAdded(Guid bag, Stat p) { IsDirty = true; }
public static Stat GetStat(byte[] dat, Pointer p, bool withInfoText, StatBag bag) { Stat s = new Stat(); s.StatID = GetInt(dat, p); float curVal = GetSingle(dat, p); s.MinValue = GetSingle(dat, p); s.MaxValue = GetSingle(dat, p); s.ForceValue(curVal); s.Owner = bag; if (withInfoText) { s.DisplayName = GetString(dat, p); s.Description = GetString(dat, p); s.Group = GetString(dat, p); } return s; }
/// <summary> /// Reads the character.xml file and returns a list of properties that that character should have /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static bool Character_GetPropertyTypesFromTemplate(string filePath, ref PropertyBag props, ref StatBag stats) { XPathDocument doc = LoadDocument(filePath, true); XPathNavigator nav = null; string[] sections = new string[] { "StringProperties", "IntProperties", "LongProperties", "FloatProperties" }; try { if (doc == null) { return false; } nav = doc.CreateNavigator(); for (int i = 0; i < sections.Length; i++) { XPathNodeIterator iter = nav.Select(@"./Template/Character/PropertyBag/" + sections[i] + "/Property"); while (iter.MoveNext()) { string id = iter.Current.GetAttribute("ID", ""); if (id == null || id.Length < 1) { Log.LogMsg("Error reading ID attribute in node " + iter.Current.InnerXml); continue; } string name = iter.Current.GetAttribute("Name", ""); if (name == null) { name = ""; } int propertyTypeID = int.Parse(id); if (sections[i] == "IntProperties") { int value = int.Parse(iter.Current.Value); props.SetProperty(name, propertyTypeID, value); } else if (sections[i] == "StringProperties") { props.SetProperty(name, propertyTypeID, iter.Current.Value); } else if (sections[i] == "FloatProperties") { float value = float.Parse(iter.Current.Value); props.SetProperty(name, propertyTypeID, value); } else if (sections[i] == "LongProperties") { long value = long.Parse(iter.Current.Value); props.SetProperty(name, propertyTypeID, value); } } } // Stats XPathNodeIterator statIter = nav.Select(@"./Template/Character/StatBag/Stat"); while (statIter.MoveNext()) { int id = int.Parse(statIter.Current.GetAttribute("StatID", "")); Stat proto = StatManager.Instance[id]; if (proto == null) { Log.LogMsg("Error reading character template. Stat id [" + id + "] was specified but was not loaded from the Stats.xml configuration file. Stat not added to character."); continue; } float currentValue = float.Parse(statIter.Current.Value); Stat s = new Stat(id, proto.DisplayName, proto.Description, proto.Group, currentValue,proto.MinValue, proto.MaxValue); stats.AddStat(s); } } catch (Exception e) { Log.LogMsg("Failed to load character properties from template."); //Log.LogMsg("Exception thrown reading Character template. " + e.Message); return false; } return true; }
/// <summary> /// Sends out notifications that a stat has been updated /// </summary> /// <param name="p">the stat that was updated</param> public void NotifyStatUpdated(Stat p) { for (int i = 0; i < m_Listeners.Count; i++) { m_Listeners[i].OnStatUpdated(this.ID, p); } }
public void OnStatUpdated(Guid bag, Stat s) { if (s.Owner != Stats) { // then it's bubbled up from outside of this object. update our stats with it Stats.AddStat(s); } }
/// <summary> /// Removes a stat object from the stat bag that has the same ID as @objStat /// </summary> /// <param name="objStat">the stat to add</param> public void RemoveStat(Stat objStat) { bool wasRemoved = false; if (m_HashedProperties != null) { wasRemoved = m_HashedProperties.Remove(objStat.StatID); } else { Stat cur = m_LinkedProperties.FirstOrDefault(s => s.StatID == objStat.StatID); if (cur != null) { wasRemoved = m_LinkedProperties.Remove(cur); } } objStat.Owner = null; if (wasRemoved) { NotifyStatRemoved(objStat); } }
/// <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 void RemoveStats(Stat[] statsToRemove) { if (statsToRemove == null) { return; } foreach (Stat s in statsToRemove) { RemoveStat(s); } }
public void OnStatAdded(Guid bag, Stat p) { }
public void SetMaxStatValue(int statId, float val) { Stat stat = GetStat(statId); if (stat == null) { Stat newSTat = new Stat(statId, "", "", "", -1, float.MinValue, val); newSTat.Owner = this; AddStat(newSTat); return; } if (stat.MaxValue != val) { stat.MaxValue = val; NotifyStatUpdated(stat); } }
public void OnStatUpdated(Guid bag, Stat p) { }
public static void AddStat(ref byte[] dat, Pointer curPointer, Stat stat) { AddStat(ref dat, curPointer, stat, true); }