Jump to content

Mythli

Members
  • Posts

    25
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Everything posted by Mythli

  1. No, Database data is by default 0 (that means dbc-data is used) Thanks for your help
  2. WAD is a very old emulator supporting patch 1.x if you want to call it so (it is more about playing with the wow world) for more info read http://www.gotwow.ic.cz/wowd/ "Database" files in WAD look like this: #include scripts/extra/creatures_auctioneers.scp ... #include scripts/afg/afgcreatures.scp #include scripts/afg/afgqiraj.scp #include scripts/chronos/chronos_vendors.scp #include scripts/chronos/chronos_creatures.scp [creature 0] name=Spawn Points (Only GM can see it) faction=35 level=255 attack=2000 2200 bounding_radius=1.5 combat_reach=2.25 damage=0 2 maxhealth=56 model=262 size=0.5 type=1 maxmana=0 money=127500 [creature 1] name=Spawn Point (Only GM can see it) faction=35 level=255 attack=2000 2200 bounding_radius=1.5 combat_reach=2.25 damage=0 2 maxhealth=56 model=262 size=0.5 type=1 maxmana=0 money=127500
  3. I have written this tool long time ago for personal use and learning reasons (first c# programm i have ever wrote) SQLUpdate Merging Tool This is my little tool for merging various sql-updates to one big update. i have written this in .net (c#) but dont look at the code it's horrible Features: 1. Support SD2, Mangos, UDB and many other SQL Update formats ^\\\\d+_{1}(\\\\d+)_{1}\\\\d+_{1}([A-Z]|[a-z]+)_{1}(.*)$", //match mangos update style (provide revision number, databasename, tablename) ^r{1}(\\\\d+)_{1}(\\\\w+).*$", //match SD2 Update style with some on official style (provide revision number& database name) ^r{1}(\\\\d+)_{1}(.*)$", //match SD2 update style (provide revision number& database name) 2. Grouping 3. Editing 4. Drag& Drop 5. Apply filter Screenshots& Explanation: Feel free to comment this tool/ post feedback. regards Mythli <3 Download: http://mythli.ath.cx/websvn/wsvn/Downloads/sqlupdatemerge_1.0/?op=dl&isdir=1& Changelog: http://mythli.ath.cx/websvn/wsvn/sqlMerge/trunk/?op=log&isdir=1& RSS: http://mythli.ath.cx/websvn/wsvn/sqlMerge/trunk/?op=rss&isdir=1& requires .net framework 2.0 or newest mono release.
  4. In the hope someone find this snippet usefull using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Text.RegularExpressions; using System.Data; namespace scpparser.Classes { public class ScpParser { public String IncludeRoot; public String FileName; public List<String> ParsedFiles = new List<String>(); private Regex IncludeSearchPattern = new Regex("^(?!//)#include\\\\s*(.*)"); private Regex SectionStartSearchPattern = new Regex("^(?!//)\\\\[(\\\\w+)\\\\s*([^]]+)\\\\]$"); private Regex ValuePairSearchPattern = new Regex("^(?!//)(\\\\w+)\\\\s*=\\\\s*(.*)$"); private String currentSection; private String currentPrimaryKey; public Dictionary<String, Dictionary<String, List<String>>> ParseResult = new Dictionary<String, Dictionary<String, List<String>>>(); public Dictionary<String, String> ParsedColumns = new Dictionary<String, String>(); public ScpParser() { } public ScpParser(String IncludeRoot, String FileName) : this() { this.Open(IncludeRoot, FileName); } public void HandleInclude(String FileName) { FileName = Path.Combine(this.IncludeRoot, FileName); this.ParseFile(FileName); } public void HandleSection(String SectionName, String PrimaryKey) { this.currentSection = SectionName; this.currentPrimaryKey = PrimaryKey; this.ParseResult.Add(PrimaryKey, new Dictionary<String, List<String>>()); } public void HandleValuePair(String ValueName, String Value) { if (String.IsNullOrEmpty(this.currentSection) || String.IsNullOrEmpty(this.currentPrimaryKey)) return; if (!this.ParseResult[this.currentPrimaryKey].ContainsKey(ValueName)) { this.ParseResult[this.currentPrimaryKey].Add(ValueName, new List<String>()); } if (!this.ParsedColumns.ContainsKey(ValueName)) this.ParsedColumns.Add(ValueName, ""); this.ParseResult[this.currentPrimaryKey][ValueName].Add(Value); } public void ParseLine(String Line) { Match match = null; match = this.IncludeSearchPattern.Match(Line); if (match.Success) { this.HandleInclude(match.Groups[1].Value); return; } match = this.SectionStartSearchPattern.Match(Line); if (match.Success) { this.HandleSection(match.Groups[1].Value, match.Groups[2].Value); return; } match = this.ValuePairSearchPattern.Match(Line); if (match.Success) { this.HandleValuePair(match.Groups[1].Value, match.Groups[2].Value); return; } } public void ParseFile(String FileName) { using (StreamReader fStream = File.OpenText(FileName)) { String line; while ((line = fStream.ReadLine()) != null) { this.ParseLine(line); } } this.ParsedFiles.Add(FileName); } public void Open(String IncludeRoot, String FileName) { this.IncludeRoot = IncludeRoot; this.FileName = FileName; this.ParseFile(FileName); } } }
  5. The Subject tells you everything you need to know Thanks in advance
  6. look at my source, i don't make anything different.
  7. that's true and... I have already said that this was just programmed for learning reasons so sscanf(..) is faster and i never said that regular expressions make the performance boost if we look at the code while(std::getline(this->fileStream, line)) { parselinehere(line); } would end in: * read line from file * parse line * waiting for parsing line to read next line until all lines are parsed with multiple threads we can read lines without waiting for parsing - on my hardware reading lines is very fast (ssd) and parsing lines is the time consuming thing. With multiple threads and a line buffer we can reduce the overhead to a minimum.
  8. "additemset" is a method in the player class which is derived from the unit class. so do research on your own before posing...
  9. i started programming with c++ a few weeks ago but i still think this is a good thing ("this->) "logical divide" member and local variables like m_ do. we are talking about 100-200ms or something around
  10. I've programmed this for learning reasons and i need some feedback (coding style, correct pointers, ...) this codesnip will parse mangos-like configuration files using regular expressions and multiple threads (you need the boost c++ libary to compile) On a AMD Phenom x4 945 (+intel ssd) this code is up to 20 times faster in parsing than the dotconfpp mangos configuration class i don't think performance matter if we parse configuration files but this is still an interesting fact. here is my code: header-file: #ifndef CONFIG_H #define CONFIG_H #include "Common.h" #include <fstream> #include <boost/regex.hpp> class Config { public: Config(std::string ConfigFileName); void ReloadConfig(); std::string GetStringDefault(std::string Name, std::string DefaultValue = ""); bool GetBoolDefault(std::string Name, bool DefaultValue = false); int GetIntDefault(std::string Name, int DefaultValue = 0); float GetFloatDefault(std::string Name, float DefaultValue = 0); std::string GetFileName() { return this->configFileName; } ~Config(); private: std::string configFileName; std::ifstream fileStream; boost::regex searchPattern; stringMapType configMap; //--used for threading boost::mutex lineBufferMutex; boost::mutex configMapMutex; std::list<std::string> lineBuffer; bool isFileFinish; void lineParser(); //-- }; #endif code-file: #include "Config.h" Config::Config(std::string ConfigFileName) { this->configFileName = ConfigFileName; this->fileStream.open(this->configFileName); if (this->fileStream.is_open()) { this->searchPattern = boost::regex("^([ \\\\t]+)?([^#][^\\\\s]+)\\\\s*=\\\\s*(?\\\\d+)|(?:\\"([^\\"]*)\\")).*$"); this->ReloadConfig(); } } void Config::lineParser() { //--keep thread alive until file is fully pushed into lineBuffer and lineBuffer is empty while(this->isFileFinish == false || this->lineBuffer.size() != 0) { //--wait until lines for parsing are avaible if (this->lineBuffer.size() == 0) boost::this_thread::sleep(boost::Posix_time::millisec(1)); //-- else { boost::match_results<std::string::const_iterator> matches; //--lock lineBuffer object this->lineBufferMutex.lock(); //copy first line into temp var std::string line = *this->lineBuffer.begin(); //remove first line from lineBuffer this->lineBuffer.pop_front(); this->lineBufferMutex.unlock(); //-- if (boost::regex_match(line, matches, this->searchPattern)) { //--insert match into our configMap (we have to lock our configMap object first) this->configMapMutex.lock(); if (matches[3].matched) //insert number (without qoutes) this->configMap.insert(std::make_pair(matches[2], matches[3])); else //insert string (in quoutes) this->configMap.insert(std::make_pair(matches[2], matches[4])); this->configMapMutex.unlock(); //-- } } //-- } } void Config::ReloadConfig() { //--reset this->configMap.clear(); this->fileStream.seekg(0, ios::beg); this->isFileFinish = false; //-- //--define variables std::string line; boost::thread_group threadPool; //-- //--create parser-threads for each logical cpu for(uint32 i = 0; i < boost::thread::hardware_concurrency(); i++) { threadPool.create_thread(boost::bind(&Config::lineParser, this)); } //-- //--push lines from file in our lineBuffer while(std::getline(this->fileStream, line)) { this->lineBuffer.push_back(line); } //-- this->isFileFinish = true; //wait until all lines are parsed threadPool.join_all(); } std::string Config::GetStringDefault(std::string Name, std::string DefaultValue) { stringMapType::const_iterator configNode = this->configMap.find(Name); if(configNode != this->configMap.end()) return configNode->second; else return DefaultValue; } bool Config::GetBoolDefault(std::string Name, bool DefaultValue) { std::string baseValue = this->GetStringDefault(Name, ""); if (baseValue == "") return DefaultValue; else return boost::lexical_cast<bool>(baseValue); } int Config::GetIntDefault(std::string Name, int DefaultValue) { std::string baseValue = this->GetStringDefault(Name, ""); if (baseValue == "") return DefaultValue; else return boost::lexical_cast<int>(baseValue); } float Config::GetFloatDefault(std::string Name, float DefaultValue) { std::string baseValue = this->GetStringDefault(Name, ""); if (baseValue == "") return DefaultValue; else return boost::lexical_cast<float>(baseValue); } Config::~Config() { this->fileStream.close(); }
  11. Mythli

    server Emulators

    mangos use multiple threads if you mean that - but i think it only support 2 logical cores fully wasn't it?
  12. public class DotConfParser : Dictionary<String, String> { public DotConfParser() :base() {} public DotConfParser(String FileName) { this.configFileName = FileName; this.Reload(); } public void Reload() { using (StreamReader streamReader = new StreamReader(File.OpenRead(this.configFileName))) { while (!streamReader.EndOfStream) { Match match = this.searchPattern.Match(streamReader.ReadLine()); if (match.Success) if (!base.ContainsKey(match.Groups[2].Value)) base.Add(match.Groups[2].Value, match.Groups[3].Value.Trim('"')); } } } private String configFileName; private Regex searchPattern = new Regex(@"^([ \\\\t]+)?([^#].+)\\\\s*=\\\\s*(?\\\\d)|(?:\\"([^\\"]*)\\")).*$", RegexOptions.Compiled | RegexOptions.Multiline); } A c# class to read mangos configuration files. Enjoy.
  13. And the "new" already very shiny wiki would be more shiny with more activity inside take this as attention
  14. If you look at DBCReader.cs you will see that there is no detection: for (int r = 0; r < header.RecordsCount; ++r) { uint key = reader.ReadUInt32(); reader.BaseStream.Position -= 4; T T_entry = reader.ReadStruct<T>(); dict.Add(key, T_entry); } He try to read a struct from DBCFile with predefined types, structure of Spell.dbc is defined in "Structure.cs" - this is exactly that what i don't want.
  15. I have done some research on mangos code (DBCLoader) and figured out that you have string-reference fields which contain a Int32 value that point to a string with the following offset: StrReadOffset = StringStartOffset + FieldValue Problem now is that i have to detect if column is a string reference or not.
  16. Today i want to figure out how to read DBC files with c# so i started programming and i wonder how i can read Strings properly (assign them to "Rows") and how to detect and remove empty columns (columns that just have "0"-Values) like many DBC-Editors do Here is my Source: (Pastebin) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Windows.Forms; /* --DBC FILE STRUCTURE-- [Header] Column Field Type Notes 1 Signature String (4-bytes) string, always 'WDBC' 2 Records Integer (4-bytes) number of records in the file 3 Fields Integer (4-bytes) number of fields per record 4 Record Size Integer (4-bytes) Fields*FieldSize (FieldSize is usually 4, but not always) 5 String Block Size Integer Size of the string block */ namespace VisualAI.Classes.World.Data { enum DBCFileDefines { SIGNATURE_LENGTH = 4, FIELD_SIZE = 4, HEADER_SIZE = 20, } class DBCFileInfo { public Int32 pRecordCount; public Int32 pFieldCount; public Int32 pRecordSize; //unused public Int32 pStringBlockSize; //unused public Int32 pStringBlockStart; public DBCFileInfo() { } public DBCFileInfo(Int32 pRowCount, Int32 pColumnCount) { this.pRecordCount = pRowCount; this.pFieldCount = pColumnCount; this.pStringBlockStart = (pRowCount * pColumnCount * (Int32)DBCFileDefines.FIELD_SIZE) + (Int32)DBCFileDefines.HEADER_SIZE +1; } } class DBCParser { private BinaryReader lBinaryReader; public String pFileName; public DBCFileInfo pDBCFileInfo = new DBCFileInfo(); private Int32 lCurrentRecordId = -1; private void lLoadDBCFile() { this.lBinaryReader = new BinaryReader(File.Open(this.pFileName, FileMode.Open)); UTF8Encoding lUTF8Encoder = new UTF8Encoding(); //should read string WDBC if file is a valid DBC file String lSignature= lUTF8Encoder.GetString(this.lBinaryReader.ReadBytes((Int32)DBCFileDefines.FIELD_SIZE)); if (lSignature != "WDBC") throw new Exception("DBCParser only read WDBC-Files!"); //after this we are @byte12 this.pDBCFileInfo = new DBCFileInfo(this.lBinaryReader.ReadInt32(), this.lBinaryReader.ReadInt32()); //unused this.pDBCFileInfo.pRecordSize = this.lBinaryReader.ReadInt32(); this.pDBCFileInfo.pStringBlockSize = this.lBinaryReader.ReadInt32(); } private Boolean lCheckForStringTerminator(Byte pByte) { if ((Int32)pByte != 0) return false; else return true; } public DBCParser(String pFileName) { this.pFileName = pFileName; this.lLoadDBCFile(); } #region misc functions public List<String> pGetColumnList(String pPrefix) { List<String> lTmpColumnList = new List<String>(); for (int i = 0; i < this.pDBCFileInfo.pFieldCount; i++) { lTmpColumnList.Add(pPrefix + i); } return lTmpColumnList; } #endregion public Boolean pNextRecord() { while (this.lCurrentRecordId < this.pDBCFileInfo.pRecordCount-1) { this.lCurrentRecordId++; return true; } return false; } #region Read-Based functions public Object pGetFieldValue(Int32 pFieldId) { if (pFieldId <= this.pDBCFileInfo.pFieldCount) { Int64 lCurrentOffset = (Int32)DBCFileDefines.HEADER_SIZE + (this.lCurrentRecordId * (Int32)DBCFileDefines.FIELD_SIZE * this.pDBCFileInfo.pFieldCount + pFieldId); this.lBinaryReader.BaseStream.Seek(lCurrentOffset, SeekOrigin.Begin); return this.lBinaryReader.Read(); } else throw new Exception("Unknown Column!"); } public Int32 pGetInt32(Int32 pFieldId) { return Convert.ToInt32(this.pGetFieldValue(pFieldId).ToString()); } public String pGetStringValue(Int32 pFieldId) { // this.pStringBlockStart = (pRowCount * pColumnCount * (Int32)DBCFileDefines.FIELD_SIZE) + (Int32)DBCFileDefines.HEADER_SIZE + 1; Int64 lCurrentOffset = this.pDBCFileInfo.pStringBlockStart; this.lBinaryReader.BaseStream.Seek(lCurrentOffset, SeekOrigin.Begin); Int32 lStringDataLength = (Int32)(this.lBinaryReader.BaseStream.Length - (Int64)lCurrentOffset); Byte[] lStringData = this.lBinaryReader.ReadBytes(lStringDataLength); List<Byte> lBytes = new List<Byte>(); Int32 lCurrentStringIT = 0; for (int i = 0; i < lStringData.Length; i++) { Byte lCurrentByte = lStringData[i]; if (this.lCheckForStringTerminator(lCurrentByte)) { Byte[] lStrByteArr = lBytes.ToArray(); UnicodeEncoding lUTF8Encoder = new UnicodeEncoding(); if (lCurrentStringIT >= pFieldId) return lUTF8Encoder.GetString(lStrByteArr); else { lCurrentStringIT++; lBytes.Clear(); } } else { lBytes.Add(lCurrentByte); } } return ""; } #endregion public void pClose() { this.lBinaryReader.Close(); } } } Example reading data from Map.dbc: (Pastebin) public static List<MapData> pGetMapList() { List<MapData> lTmpMapDataList = new List<MapData>(); DBCParser lDBCParser = new DBCParser(Settings.Instance.pDBCPath + "/Map.dbc"); Int32 i = 0; while (lDBCParser.pNextRecord()) { MapData lTmpMapData = new MapData(); lTmpMapData.pID = lDBCParser.pGetInt32(0); lTmpMapData.pName = lDBCParser.pGetStringValue(i); lTmpMapDataList.Add(lTmpMapData); i++; } return lTmpMapDataList; } Reading Strings work just "fine" but i can't assign them to rows because i just have many strings one after one without any logical "order" (in my eyes). My code in "GetStringValue" is working but 100% no solution because it exponential take longer if you want to select a entry in a column/row (also a problem i can't assign string values to rows) in reason i always have to loop through all bytes, count existing strings and return the right one because i cant (?) set a pointer to specific string value. Any suggestions?
  17. This is just a core modification, you have to apply his "eye of archerus" demo patch to get this quest working.
  18. Trinity include lots of code-hacks and unclean code in my opinion trinity will fail in all soon. if you want to have a stable server which is forward looking choose mangos, for now trinity has less bugs that are spell related and some realy nice additional features for developpers - it's your choice. My choice is ManGOS (which trinity is based on) for several important reasons.
  19. no they can't be moved to database - but why break mangos style rules including spirit healers into core, if you realy don't want to user sd2 scripts which are required for quests, honor reward vendors etc just remove scripts from project file and only leave the bg scripts
  20. A role-based right system only have benefits because you can just do "the old thing" I'm a Web-developper, all things that our company manage or developp have role based right management because it's more flexible, stable and comfortable for us and our customers. Maybe someone who has the time and skill to implement this very nice feature will read this thread and start developping. Mythli<3
  21. push - pls commi this to master.
  22. Create a vector of guids (i would add guidids in OnCreatureCreate() as you already mentioned) The function just have to loop through the vector and check if a creature is alive when return true.
  23. This is my little tool for merging various sql-updates to one big update. i have written this in .net (c#) but dont look at the code it's horrible Features: * Support SD2, Mangos, UDB and many other SQL Update formats "^\\\\d+_{1}(\\\\d+)_{1}\\\\d+_{1}([A-Z]|[a-z]+)_{1}(.*)$", //match mangos update style (provide revision number, databasename, tablename) "^r{1}(\\\\d+)_{1}(\\\\w+).*$", //match SD2 Update style with some on official style (provide revision number& database name) "^r{1}(\\\\d+)_{1}(.*)$", //match SD2 update style (provide revision number& database name) * Grouping * Editing * Drag& Drop * Apply filter Screenshots& Explanation: Feel free to comment this tool/ post feedback. regards Mythli <3 Source: http://filebeam.com/6bd3af107f09ff920c44be5dd3779862 Binary: http://filebeam.com/40a671bbe6924adbaa694dfab3863ee7 requires .net framework 2.0 or newest mono release.
  24. Microsoft allowed Mono to copy or clone whatever their libary Most things of the .net development framework are fully ported so in my eyes c# ist a language that allows you to write multi.os programms Mythli <3
  25. Bump, need this fix for a sd2 script (zereketh the unbound in arcatraz)
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use