从spell.dbc中提取技能名称

 昨天闲着无聊把wow2.33中的技能说明都给提取了出来,想在自己单机版的武器上添加绿字技能玩,下面是代码(我比较懒所以只提取的技能ID,名称和说明部分,好多地方的实现不是很好)
Spell.dbc结构:

Header(文件头20字节)

Records.................行数(4字节)

Fields....................列数(4字节)

Record Size...............每行所占字节(4字节)

String Block Size.....字符区所占字节(4字节)

Data(数据区 共Records * Record Size字节)-----存技能各种数据
row1.....(占Record Size字节)
row2.....(占Record Size字节)

Text(字符区 共String Block Size字节)------存技能文字说明等字符信息
第一行总为\0,后面的遇到\0为一行
例:技能名称提取  先由Data中找出技能名称所在字段,在127列*4byte=508byte位置得到技能名称在Text区的偏移量,String Block Size+偏移量就能得到技能名称的位置

 

 

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace WowItemTool
{
    [Serializable]
    
public class spellInfo
    
{
        
public int id;
        
public string name, type, memo;
    }


    
class spell
    
{

        
private byte[] m_stringTable;
        
private byte[] rowData;

        
public List<spellInfo> GetSpellList()
        
{
            
int rows, cols, rlen, tlen;

            List
<spellInfo> list=new List<spellInfo>();
            
            
//打开文件
            FileStream file = new FileStream("c:\dbc\spell.dbc",FileMode.Open,FileAccess.Read);
            BinaryReader br
= new BinaryReader(file);

            
//取文件头信息
            if (br.ReadUInt32() != 0x43424457// WDBC标志
                return list;

            rows 
= br.ReadInt32();//行数
            cols = br.ReadInt32();//列数
            rlen = br.ReadInt32();//行占字节
            tlen = br.ReadInt32();//文本块字节


            
//读取文本块
            br.BaseStream.Position = br.BaseStream.Length-tlen;
            
byte[] stringTable = br.ReadBytes(tlen);
            m_stringTable 
= stringTable;


            
//读技能信息
            br.BaseStream.Position = 20;
            
for (int i = 0; i < rows; i++)
            
{
                spellInfo spell 
= new spellInfo();
                rowData 
= br.ReadBytes(rlen);
                spell.id 
= GetInt32(rowData, 0);//技能ID
                spell.name = GetString(rowData, 127).Replace(''' ').Trim();//技能名称
                spell.type = GetString(rowData, 144).Replace(''' ').Trim();//技能属性
                spell.memo = GetString(rowData, 161).Replace(''' ').Trim();//技能介绍                
                list.Add(spell);
            }

                
            file.Close();


            SaveTxt(
"c:\MyFile.txt",list);
            
//BINserializer("c:\MyFile.txt", list);
            
//List<spellInfo> l = (List<spellInfo>)BINDeserialize("c:\MyFile.txt");
            
//XMLserializer("c:\record.xml", list, new Type[] { typeof(spellInfo) });
            
//sp1 = (List<spellInfo>)XMLDeserialize("c:\record.xml",list, new Type[] { typeof(spellInfo) });
            return list;
        }

    
//导出到纯文本
        public void SaveTxt(string fn, List<spellInfo> list)
        
{
            FileStream file 
= new FileStream(fn, FileMode.OpenOrCreate);
            StreamWriter sw 
= new StreamWriter(file);
            
for (int i = 0; i < list.Count; i++)
                sw.WriteLine(list[i].id 
+ " " + list[i].name + " " + list[i].type + " " + list[i].memo);
            sw.Close();
        }

    
//序列化二进制文件
        public void BINserializer(string fn, object o)
        
{
            IFormatter formatter 
= new BinaryFormatter();
            Stream stream 
= new FileStream(fn, FileMode.Create,FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, o);
            stream.Close();
        }

    
//反序列化二进制文件
        private object BINDeserialize(string fn)
        
{
            IFormatter formatter 
= new BinaryFormatter();
            Stream stream 
= new FileStream(fn, FileMode.Open,FileAccess.Read, FileShare.Read);
            
object ro = formatter.Deserialize(stream);
            stream.Close();
            
return ro; 
        }

    
//序列化XML文件
        public void XMLserializer(string fn,object o,Type[] type)
        
{
            XmlSerializer serializer 
= new XmlSerializer(o.GetType(), type);
            TextWriter writer 
= new StreamWriter(fn);
            serializer.Serialize(writer, o);
            writer.Close();
        }

    
//反序列化XML文件
        private object XMLDeserialize(string fn, object o,Type[] type)
        
{
            XmlSerializer Serializer 
= new XmlSerializer(o.GetType(), type);
            TextReader read 
= new StreamReader(fn);
            
object ro=Serializer.Deserialize(read);
            read.Close();
            
return ro;
        }



        
public string GetString(byte[] data, uint field)
        
{
            System.Text.UTF8Encoding converter 
= new System.Text.UTF8Encoding();
            
uint startOffset = GetUInt32(data, field);
            
byte[] s=new byte[1024];
            
int i = 0;
            
while ((s[i] = m_stringTable[startOffset++]) != 0)
            
{
                i
++;
            }

            
return converter.GetString(s);
        }


        
protected static unsafe uint GetUInt32(byte[] data, uint field)
        
{
            
uint startIndex = field * 4;
            
if (startIndex + 4 > data.Length)
                
return uint.MaxValue;

            
fixed (byte* pData = &data[startIndex])
            
{
                
return *(uint*)pData;
            }

        }


        
protected static unsafe int GetInt32(byte[] data, uint field)
        
{
            
uint startIndex = field * 4;
            
if (startIndex + 4 > data.Length)
                
return int.MaxValue;

            
fixed (byte* pData = &data[startIndex])
            
{
                
return *(int*)pData;
            }

        }


       


       


    }

}

 

本文原创,由csdn搬家过来

posted on 2009-06-15 00:34  史琳  阅读(1094)  评论(0编辑  收藏  举报

导航