找回密码
 立即注册
GTA5修改器.风灵月影生化危机7修改器.风灵月影三国志13修改器.风灵月影讨鬼传2修改器.风灵月影猎天使魔女修改器.风灵月影
刺客信条修改器虐杀原形2修改器.风灵月影看门狗2修改器.风灵月影鬼泣5修改器.风灵月影上古卷轴5修改器
查看: 51|回复: 0

C#梦幻西游和大话3地图读取(源代码请自行转化为VC++)

[复制链接]

2604

主题

2627

帖子

8001

积分

论坛元老

Rank: 8Rank: 8

积分
8001
发表于 2017-7-3 21:14:32 | 显示全部楼层 |阅读模式
01.jpg
代码是C#的,请自行转化为其他语言。
/////////////////////////////////////////////////////////              /梦幻西游map文件结构
/*=======================MAP HEAD===============================
4字节 XPAM(MAPX)
4字节 地图的宽度
4字节 地图的高度

4*n字节 地图单元的引索 n=地图的宽度/640*2 * 地图高度/480*2
4字节 多出的一个地图单元引索,即结束引索,也就是文件的大小。

4字节 HGPJ (JPGH)
4字节 JPG头的大小
n字节 数据内容 n=JPG头的大小,不包括前面8字节。

==============================================================

4字节 地图单元引索的开始位置,也是KSAM的数量。

4字节 GAMI (IMAG)
4字节 大小(153600),正好是320x240x2。
n字节 数据,不包括前面8字节。

4字节 GEPJ (JPEG)
4字节 JPEG单元大小,不包括这8字节。
2字节 单元地图的宽度
2字节 单元地图的高度
n字节 地图数据

4字节 KSAM (MASK)
4字节 大小(不定)
n字节 数据,不包括前面8字节。
:
4字节 KSAM (MASK)
4字节 大小(不定)
n字节 数据,不包括前面8字节。


4字节 KOLB (BLOK)
4字节 大小(9600)
n字节 数据,不包括前面8字节。

4字节 LLEC (CELL)
4字节 大小(192)
n字节 数据,不包括前面8字节。

4字节 GIRB (BRIG)
4字节 大小(不定)
n字节 数据,不包括前面8字节。

8字节 结束单元。

==============================================================

XPAM (MAPX) 地图文件头
Index       图象单元引索
HGPJ (JPGH) 图象JPEG Head

GAMI (IMAG) 只有1028.map地图含有这个单元。
GEPJ (JPEG) 图象数据
KSAM (MASK)
:
KSAM (MASK)
KOLB (BLOK) 遮掩规则,一比特代表一个地图像素。
LLEC (CELL) 地图规则,一字节代表一个游戏坐标。
GIRB (BRIG) 光亮规则
:
:
:
GAMI (IMAG) 只有1028.map地图含有这个单元。
GEPJ (JPEG) 图象数据
KSAM (MASK)
:
KSAM (MASK)
KOLB (BLOK) 遮掩规则,一比特代表一个地图像素。
LLEC (CELL) 地图规则,一字节代表一个游戏坐标。
GIRB (BRIG) 光亮规则
************************************************************************/

/************************************************************************
Map File New Format


======================= MAP HEAD =============================
4字节 0.1M (M1.0) 0x302E314D
4字节 地图的宽度
4字节 地图的高度

4*n字节  地图单元的引索 n=地图的宽度/640*2 * 地图高度/480*2

4字节 文件头大小,包括这4字节,及以上的字节。
==============================================================

======================= Unknown ==============================
n字节 未知用途,大小为:第一个单元引索值减去文件头大小。
注意:这个格式中还没有发现旧格式中的KOLB、GAMI和KSAM。
有可能和这些单元的用途相同。
==============================================================

======================= Unit Data ============================
4字节 地图单元引索的开始位置。
n*4字节 n为上面的值,n为0时不存在。

4字节 GEPJ (JPEG)
4字节 大小
n字节 数据

4字节 LLEC (CELL)
4字节 大小
n字节 数据

4字节 BRIG (GIRB)
4字节 大小
n字节 数据

4字节 结束单元。
==============================================================

0.1M                新地图文件头        
Index                数据块引索

Unknown         n字节,未知用途(暂称为HEAD)

GEPJ(JPEG)        图象数据
LLEC(CELL)        地图规则,一字节代表一个游戏坐标
GIRB(BRIG)        光亮规则
:
:
:
GEPJ(JPEG)        图象数据
LLEC(CELL)        地图规则,一字节代表一个游戏坐标
GIRB(BRIG)        光亮规则

************************************************************************/

/************************************************************************
大话西游3的MAP格式
Dali Wang <wdl@sina.com>
2007-05-18

=========== MAP HEAD ============
4字节 文件标志 0.3M (M3.0) 0x524F4C30
4字节 保留(未知作用,应该都为0)
4字节 地图实际的宽度
4字节 地图实际的高度
2字节 坐标的宽度(默认:20px)
2字节 坐标的高度(默认:20px)
2字节 小地图的宽度(默认:400px)
2字节 小地图的高度(默认:320px)
4字节 单元引索的位置
4字节 单元引索的数量
4字节 引索的位置(未知部分)
4字节 引索的数量(未知部分)

=========== UNIT INDEX =========
4字节*n 单元的引索      

========== 未知数据 ============
可能是地图遮掩关系等数据

========== UNIT DATA ===========
4字节 MASK(KSAM) 遮掩关系
4字节 大小
n字节 数据

4字节 JPEG(GEPJ) JPEG 图片数据
4字节 大小
n字节 数据

4字节 CELL(LLEC) 地图行走规则
4字节 大小
n字节 数据

4字节 LIGT(TGIL) 地图亮度规则
4字节 大小
n字节 数据

4字节 END ( DNE) 单元结束标志
4字节 大小

////////////////////////////////
HEADER 40字节

INDEX
......
INDEX

未知数据

MASK (KSAM) 0x4D41534B
MSK2 (2KSM) 0x4D534B32
JPEG (GEPJ) 0x4A504547
CELL (LLEC) 0x43454C4C
LIGT (TGIL) 0x4C494754
END  ( DNE) 0x454E4420
:
:
:
MASK (KSAM) 0x4D41534B
MSK2 (2KSM) 0x4D534B32
JPEG (GEPJ) 0x4A504547
CELL (LLEC) 0x43454C4C
LIGT (TGIL) 0x4C494754
END  ( DNE) 0x454E4420
************************************************************************/

/************************************************************************
大话3地图 ROL 文件格式
Dali Wang<wdl@sina.com>
2007-05-18

=========== FILE HEAD ==========
24字节
4字节 文件标志 0LOR(ROL0)
4字节 保留 (00 00 00 00)
4字节 大地图的宽度
4字节 大地图的高度
2字节 小地图的宽度
2字节 小地图的高度
4字节 引索的数量

=========== JPEG INDEX =========
n*4字节 引索列表

=========== JPEG DATA ==========
4字节 47 45 50 4A 标志 GEPJ(JPEG)
4字节 B7 20 00 00 数据大小
n字节 数据
:
:
:
4字节 47 45 50 4A 标志 GEPJ(JPEG)
4字节 数据大小
n字节 数据

************************************************************************/


using System;
using System.IO;
using System.Text;

namespace 梦幻西游地图读取
{
    public class MHXYMap
    {


       #region 地图的组成
                 /////////////////////////////////////////////////////////////////////地图的组成
        /// <summary>
        /// 地图头
        /// </summary>
        class MapHeader
        {
            public UInt32 Flag;                                  //文件标志
            public UInt32 MapWidth;                             // 地图的宽度
            public UInt32 MapHeight;                            // 地图的高度

        }

         /// <summary>
        ///  地图的单元头
         /// </summary>
            class UnitHeader
        {
            public UInt32 Flag;
            public UInt32 Size;
            }

        /// <summary>
        /// 地图的数据
        /// </summary>
            public  class MapData
            {
            public UInt32 Size;                                            // 数据大小
            public byte []Data;                                             // 数据内容
            }

        #endregion

        private string path;
        private FileStream mapfile;
        private MapHeader mapHeader;
        private  MapData     mapData;

        /// <summary>
        /// 是梦幻西游地图的标志
        /// </summary>
        private const uint MHXYFlag = 0x4D312E30;


        public MHXYMap(string mappath)
        {
            try
            {
                path = mappath;
                mapfile = File.OpenRead(mappath);
                mapHeader=new MapHeader();
                mapData=new MapData();



                m_SubMapWidth = 320;// 子地图的宽度
                m_SubMapHeight = 240;// 子地图的高度
                m_PointWidth = 20;// 坐标的宽度
                m_PointHeight = 20;// 坐标的高度
            }
            catch { }

        }


         public int m_MapWidth;                                                                    // 地图的宽度
         public int m_MapHeight = 0;                                                        // 地图的高度
         public int m_SubMapWidth =320;                                                        // 子地图的宽度
         public int m_SubMapHeight = 240;                                                        // 子地图的高度
         public int m_PointWidth = 20;                                                        // 坐标的宽度
         public int m_PointHeight = 20;                                                        // 坐标的高度
         public int m_SubMapRowNum = 0;                                                        // 子地图的行数量
         public int m_SubMapColNum = 0;                                                        // 子地图的列数量
         public int m_SubMapTotal = 0;                                                        // 子地图的总数
         public int m_MapSize = 0;                                                                // 地图的大小

         public int m_Reserved = 0;                                                                // 保留
         public int m_UnitIndexOffset = 0;                                                // 单元的引索位置
         public int m_UnitIndexNum = 0;                                                        // 单元的引索数量
         public int m_IndexOffset = 0;                                                        // 引索位置(未知部分)
         public int m_IndexNum = 0;                                                                // 引索数量(未知部分)

         public int [] m_UnitOffsetList;                                                // 单元的偏移列表
                 public int [] m_OffsetList;                                                        // 未知部分的偏移列表

         public int m_MaskNum = 0;                                                                // MASK 的数量
         public int[] m_MaskList;                                                                // MASK
         public int m_MaskTemp = 0;                                                                // MASK 临时变量

         public bool m_isJpgh = false;
         public bool m_isHead = false;
         public bool m_isImag = false;
         public bool m_isJpeg = false;
         public bool m_isMask = false;
         public bool m_isBlok = false;
         public bool m_isCell = false;
         public bool m_isBrig = false;
         public bool m_isLigt = false;


         public MapData m_jpgh;                                                                // JPGH 数据
         public MapData m_head;                                                                // HEAD 数据
         public MapData m_imag;                                                                // IMAG 数据
         public MapData m_jpeg;                                                                // JPEG 数据
         public MapData[] m_mask;                                                // MASK 数据
         public MapData m_blok;                                                        // BLOK 数据
         public MapData m_cell;                                                                // CELL 数据
         public MapData m_brig;                                                                // BRIG 数据
         public MapData m_ligt;                                                                // LIGT 数据

                UnitHeader m_ErrorUnit;                                                        // 错误单元的标志


        // 文件标志  
        // 0x4D415058 (MAPX) 大话2旧地图
        // 0x4D312E30 (M1.0) 大话2新地图 梦幻地图 /////////////
        // 0x4D322E35 (M2.5) 大话3内测版
        // 0x4D332E30 (M3.0) 大话3正式版
        // 0x524F4C30 (ROL0) 大话3地图背景文件


        public void AnalyseMap()
        {
            byte []temp=new byte[12];
            mapfile.Read(temp,0,12);
            mapHeader.Flag=BitConverter.ToUInt32(temp,0);  
            mapHeader.MapWidth=BitConverter.ToUInt32(temp,4);
            mapHeader.MapHeight=BitConverter.ToUInt32(temp,8);

            m_MapWidth= (int)mapHeader.MapWidth;
            m_MapHeight=(int)mapHeader.MapHeight;

            // 注:因为有些地图的尺寸并一定可以被小地图尺寸整除,所以需要趋向最大取整
            m_SubMapRowNum=(int)Math.Ceiling( (double)m_MapHeight/m_SubMapHeight); // 计算行中子地图的数量
                    m_SubMapColNum=(int)Math.Ceiling( (double)m_MapWidth/m_SubMapWidth); // 计算列中子地图的数量
            m_SubMapTotal=m_SubMapRowNum*m_SubMapColNum; // 计算地图中总的子地图数量

            // 读取单元偏移值列表
                    m_UnitOffsetList=new int[m_SubMapTotal]; // 自动分配列表空间
            byte []unit=new byte[m_SubMapTotal*4];
            mapfile.Read(unit,0, m_SubMapTotal * 4);
                  //  infile.read((char*)m_UnitOffsetList, sizeof(uint32) * m_SubMapTotal); // 读取列表
                for(int i=0;i<m_SubMapTotal;i++)
            {
              m_UnitOffsetList=(int)BitConverter.ToUInt32(unit,i*4);
            }


            // 读取新地图HEAD的数据
            byte[] headbyte = new byte[8];
            mapfile.Read(headbyte, 0, 8);
            m_MapSize = (int)BitConverter.ToUInt32(headbyte, 0);// 获得文件头的大小
            mapData.Size = BitConverter.ToUInt32(headbyte, 4); // 获得Head的大小

            mapData.Data = new byte[mapData.Size];
            mapfile.Read(mapData.Data, 0, (int)mapData.Size);//// 读取地图头数据

            mapfile.Close();
        }

        /// <summary>
        /// 读取地图的单元数据
        /// </summary>
        /// <param name="unitnum"></param>
        public void ReadUnit(int unitnum)
        {
            int seek;                // 跳转地址
            bool Result;                // 结果
            bool loop = true;                // 是否循环
            m_MaskTemp = 1;

            m_isMask = false;
            m_isJpeg = false;
            m_isCell = false;
            m_isLigt = false;
            FileStream fs = File.OpenRead(path);
            seek = m_UnitOffsetList[unitnum];
            fs.Seek(seek, SeekOrigin.Begin);  //// 跳转到单元开始的位置
            byte[] masknum = new byte[4];
            fs.Read(masknum, 0, 4);
            m_MaskNum = BitConverter.ToInt32(masknum, 0);
            m_MaskList = new int[m_MaskNum];

            byte[] masklist = new byte[m_MaskNum*4];
            fs.Read(masklist, 0, m_MaskNum * 4);
            for (int i = 0; i < m_MaskNum; i++)
            {
                m_MaskList = (int)BitConverter.ToUInt32(masklist, i * 4);
            }

            UnitHeader unit = new UnitHeader();
            byte []u=new byte[8];
            while(loop)
                 {
                fs.Read(u,0,8);

                        unit.Flag=BitConverter.ToUInt32(u,0)   ; // 读取单元的头数据
                unit.Size=BitConverter.ToUInt32(u,4);


                switch (unit.Flag)
                {


                    // GEPJ "47 45 50 4A"
                    case 0x4A504547:
                        Result = ReadJPEG(fs, unit.Flag, unit.Size);
                        break;

                    // LLEC "4C 4C 45 43"
                    case 0x43454C4C:
                        Result = ReadCELL(fs, unit.Flag, unit.Size);
                        break;

                    // GIRB "47 49 52 42"
                    case 0x42524947:
                        Result = ReadBRIG(fs, unit.Flag, unit.Size);
                        break;

                    // 默认处理
                    default:
                        // 错误标志
                          m_ErrorUnit = new UnitHeader();
                          m_ErrorUnit.Flag=unit.Flag;
                          m_ErrorUnit.Size=unit.Size;
                        loop = false;
                        break;
                }
                 }
               fs.Close();
           
     }

            // 读取地图JPEG的数据
            bool ReadJPEG(FileStream fs, UInt32 Flag, UInt32 Size)
            {
                    if (Flag==0x4A504547)
                    {
                            m_isJpeg = true;
                    m_jpeg=new MapData();
                            m_jpeg.Data = new byte[Size]; // 分配单元数据的内存空间
                            fs.Read(m_jpeg.Data,0,(int)Size); // 读取单元JPEG的数据
                            m_jpeg.Size=Size;

                    }
                    else
                    {
               
                            m_isJpeg = false;
                            return false;
                    }
                    return true;
            }


            // 读取地图CELL的数据
            bool ReadCELL(FileStream fs, UInt32 Flag, UInt32 Size)
            {
                    if (Flag==0x43454C4C)
                    {
                            m_isCell = true;
                    m_cell=new MapData();
                            m_cell.Data = new byte[Size]; // 分配单元数据的内存空间
                            fs.Read(m_cell.Data,0,(int)Size); // 读取单元CELL的数据
                            m_cell.Size=Size;
                    }
                    else
                    {
               
                            m_isCell = false;
                            return false;
                    }
                    return true;
            }

            // 读取地图BRIG的数据
            bool ReadBRIG(FileStream fs, UInt32 Flag, UInt32 Size)
            {
                    if (Flag == 0x42524947)
                    {
                            m_isBrig = true;
                    m_brig=new MapData();
                            m_brig.Data = new byte[Size];
                            fs.Read(m_brig.Data,0,(int)Size); // 分配单元数据的内存空间
                            m_brig.Size=Size;
                    }
                    else
                    {
               
                            m_isBrig = false;
                            return false;
                    }
                    return true;
            }












        /// <summary>
        /// 判断是否为梦幻西游地图文件
        /// </summary>
        /// <param name="mappath"></param>
        /// <returns></returns>
         public bool IsMHXYMap()
         {
             byte []flag=new byte[4];

             mapfile.Read(flag, 0, 4);

             if (BitConverter.ToInt32(flag,0) == MHXYFlag)
             {
                 return true;
             }
             else
             {
                 return false;
             }
         }
    }

}
梦幻西游地图读取.rar (70.31 KB, 下载次数: 0, 售价: 100 金钱)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表