首页
最新活动
服务器租用
香港服务器租用
台湾服务器租用
美国服务器租用
日本服务器租用
新加坡服务器租用
高防服务器
香港高防服务器
台湾高防服务器
美国高防服务器
裸金属
香港裸金属服务器
台湾裸金属服务器
美国裸金属服务器
日本裸金属服务器
新加坡裸金属服务器
云服务器
香港云服务器
台湾云服务器
美国云服务器
日本云服务器
CDN
CDN节点
CDN带宽
CDN防御
CDN定制
行业新闻
官方公告
香港服务器资讯
帮助文档
wp博客
zb博客
服务器资讯
联系我们
关于我们
机房介绍
机房托管
登入
注册
帮助文档
专业提供香港服务器、香港云服务器、香港高防服务器租用、香港云主机、台湾服务器、美国服务器、美国云服务器vps租用、韩国高防服务器租用、新加坡服务器、日本服务器租用 一站式全球网络解决方案提供商!专业运营维护IDC数据中心,提供高质量的服务器托管,服务器机房租用,服务器机柜租用,IDC机房机柜租用等服务,稳定、安全、高性能的云端计算服务,实时满足您的多样性业务需求。 香港大带宽稳定可靠,高级工程师提供基于服务器硬件、操作系统、网络、应用环境、安全的免费技术支持。
联系客服
服务器资讯
/
香港服务器租用
/
香港VPS租用
/
香港云服务器
/
美国服务器租用
/
台湾服务器租用
/
日本服务器租用
/
官方公告
/
帮助文档
魔兽服务器学习-笔记(服务器部署、地图管理、DB、日志模块、任务模块、战斗模块)
发布时间:2024-03-08 06:48:10 分类:帮助文档
魔兽服务器学习-笔记(服务器部署、地图管理、DB、日志模块、任务模块、战斗模块) 文章目录 一、环境准备1)依赖安装2)源码下载和编译 二、生成数据信息1)地图数据信息(客户端信息)2)数据库信息 三、启动服务器四、日志模块五、数据库模块六、场景模块1)地图管理2)AOI算法1、静态数据讲解2、动态数据:3、动态数据结构NGrid解析4、涉及用户登录的逻辑及grid状态转变5、涉及玩家退出的逻辑及grid状态转变 3)地图数据驱动1)网络驱动2)地图定时更新做的事 4)动态数据管理(1)设计模式-访问者模式及代码表现形式 5)碰撞检测实现(BIH+AABB) 七、战斗模块1)技能模块①技能信息类SpellInfo 八、MMO常用模块(任务、副本、商店等)九、AI十、游戏实体代码1)trinitycore实体类介绍2)分开介绍各实力类(1)object类 十、背包模块 一、环境准备 1)依赖安装 sudo apt-get update sudo apt-get install git clang cmake gcc g++ libmysqlclient-dev libss-dev libbz2-dev libreadline-dev libncurses-dev libboost-all-dev mysql-server-5.7 p7zip sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang 100 // sudo yum install -y clang 2)源码下载和编译 git clone -b 3.3.5 https//github.com//TrinityCore/TrinityCore.git mkdir build cd build cmake ../ -DCMAKE_INSTALL_PREFIX=/home/lighthouse/tinycore -DCONF_DIR=/home/lighthouse/tinycore/bin make -j2 (nproc看核心数来编译) make install 二、生成数据信息 1)地图数据信息(客户端信息) 1)cd ~ 2)mkdir res (根目录创建res文件夹) 3)把客户端目录的Data和Interface移动到res目录下 4)cd res 在res目录执行游戏目录bin/下面的mapextractor, 生成dbc和maps文件夹 5)mkdir vmaps 在res目录执行游戏目录bin/下面的vmap4extractor, 生成vmaps文件夹和Buildings目录 5)在res目录执行游戏目录bin/下面的vmap4assembler, ../lighthouse/bin/vmap4assembler Buildings vmaps 6) mkdir mmaps 在res目录执行游戏目录bin/下面的mmaps_generator 生成mmaps目录 2)数据库信息 注意 需要提前安装mysql mysql -uroot -p password 1)在TrinityCore的sql/create目录的路径赋值,打开mysql mysql> source ../Trinity/sql/create/create_mysql.sql show database; 可以看到生成了auth \ character \ world 三、启动服务器 1)先进到项目的bin目录,复制authserver.conf 启动授权服务器 ./authserver 2)同样步骤,复制worldserver.conf 并且改写DataDir,指定res目录 DataDir="../../res" 启动worldserver 启动授权服务器 ./worldserver 四、日志模块 五、数据库模块 六、场景模块 1)地图管理 ①哪些模块会用到地图模块? 1)运动模块:走、跳、飞行 2)副本 3)寻路 ②地图模块要实现哪些功能? 1)AOI:管理地图地理信息、地图对象信息 2)功能:视野、数据同步、碰撞检测、寻路算法 ③怎么驱动地图模块? 1)移动的网络数据驱动 2)定时更新(怪物的AI行为) 2)AOI算法 职责: ①静态数据: 《1》trinity由mapextractor生成.map文件(基础地图信息),数据包括 1) area data (区域物体信息) 2) height data (高度信息) 3) liquid data (水) 4) hole data (洞) 《2》由mmaps_generator生成可移动地图信息 .mmap,游戏中的地图移动数据(用来给navmesh寻路),也就是用recast和detour生成寻路信息 1) mmtile 索引对应具体地图的所有信息(x+y做名字前缀) 2) .mmap 索引 《3》vmapsextractor生成地图元素信息(可视场景信息:山脉、水体、建筑物等静态场景信息),用于未来做碰撞检测, *.m2和 *.wmo文件 静态物品包围盒信息 *.mdx 角色、物品和怪物包围盒信息 《4》vmap4assembler合并vmapsextractor和mmaps_generator生成的地图信息,vmtile信息 ②动态数据 1、静态数据讲解 NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; //NGridType是动态数据 GridMap* GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; //原始数据,最新的已去除 //静态数据,64*64的格子, //每个格子是8*8个cell,grid和cell都有自己的坐标系 //动物、角色、怪物都是在具体的cell当中 std::bitset
marked_cells; 2、动态数据: 玩家在哪个grid的cell,哪个grid才会被加载,否则不会被加载到内存当中 (只有玩家进入这个区域才会动态加载这个区域的资源) 3、动态数据结构NGrid解析 ①数据结构 //NGridType是模板类 extern template class NGrid
; typedef NGrid
NGridType; AllWorldObjectTypes:(动态的obj) player玩家、宠物、尸体、动态物品(远处target) typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes; AllGridObjectTypes :(静态的obj) 游戏obj、除了宠物的obj、动态物体、尸体 typedef TYPELIST_7(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger, SceneObject, Conversation) AllGridObjectTypes; ②具体分析 NGrid有两个容器:i_container和i_objects private: uint32 i_gridId; GridInfo i_GridInfo; GridReference
> i_Reference; int32 i_x; int32 i_y; grid_state_t i_cellstate; GridType i_cells[N][N]; bool i_GridObjectDataLoaded; typedef Grid
GridType; class Grid private: TypeMapContainer
i_container; TypeMapContainer
i_objects; 玩家进入某个grid的cell,地图加载数据激活推动消息推送 4、涉及用户登录的逻辑及grid状态转变 MapRefManager m_mapRefManager;//MapRefManager双向循环链表 1)根据地图ID、xyz轴、面向在地图上准备new obj 2)把玩家链接到这个地图对应的双向循环链表上 3)根据玩家坐标创建一个cell,加载玩家到对应地图的内存上,若这个cell只有一个玩家则加载cell全部地图信息 4)把玩家的包围盒和怪物、NPC、玩家用BSP tree包围盒做碰撞检测(访问者模式) DynamicMapTree _dynamicTree; void Balance() { _dynamicTree.balance(); } 5、涉及玩家退出的逻辑及grid状态转变 1)当定时器超时玩家没重连,那就把玩家从当前地图清除 ⑤地图的状态 1)Idle 2)Active 3)InValid //无效状态 4)REMOVAL //准备从内存中卸载 地图状态转换说明: ①起伏创建是Invalid, ②加载具体cell到grid里面是Idle状态, ③当把玩家放进来的时候是Active状态, ④当玩家退出或掉线时候,这个cell是无人的时候,变为Idle状态 ⑤当超时重连结束,玩家被从地图删除实例,则是Removal状态,下次服务器tick触发的时候把地图从内存卸载 (魔兽主线程等待子线程update地图事件,全部结束后才往下把所有map走delayUpdate,更新地图状态机,走从内存卸载删除逻辑) typedef enum { GRID_STATE_INVALID = 0, GRID_STATE_ACTIVE = 1, GRID_STATE_IDLE = 2, GRID_STATE_REMOVAL= 3, MAX_GRID_STATE = 4 } grid_state_t; 3)地图数据驱动 玩家进入某个grid的cell,地图加载数据激活推动消息推送 1)网络驱动 网络结构说明 ①创线程池A,线程主要做: 1)信号处理 2)远程连接请求 3)数据库心跳 4)生成core检查 5)异步日志 ... ②主线程有主循环,按照一定频率update游戏世界逻辑,执行的逻辑比如 1)更新玩家session信息,根据玩家连接状态更改session状态 (如果不是线程安全,那就在主线程处理,后面的业务逻辑是多线程处理的) 2)主线程处理的逻辑包括:从数据库获取基础的玩家初始数据比如背包等 3)其他线程中的处理:在地图中攻击、寻路、走路 ③线程池B,主要处理地图数据 读取配置中的线程数量,创建线程池,并给每条线程发更新地图的放到阻塞的任务队列,每条map也能处理来自客户端发送的数据包 void MapManager::Update(uint32 diff) { i_timer.Update(diff); if (!i_timer.Passed()) return; MapMapType::iterator iter = i_maps.begin(); while (iter != i_maps.end()) { if (iter->second->CanUnload(diff)) { if (DestroyMap(iter->second)) iter = i_maps.erase(iter); else ++iter; continue; } if (m_updater.activated()) m_updater.schedule_update(*iter->second, uint32(i_timer.GetCurrent())); else iter->second->Update(uint32(i_timer.GetCurrent())); ++iter; } if (m_updater.activated()) m_updater.wait(); for (iter = i_maps.begin(); iter != i_maps.end(); ++iter) iter->second->DelayedUpdate(uint32(i_timer.GetCurrent())); i_timer.SetCurrent(0); } ④线程池C用来负载均衡处理客户端发包(Network) 2)地图定时更新做的事 ①更新这个地图中的玩家,用访问者模式给玩家广播周围的obj(让自己在同cell里面被其他人看到),处理视野相关内容 ②包围盒_dynamicTree二叉树检测物体碰撞(惰性更新,每次更新的时候进行平衡) void Map::Update(uint32 t_diff) { _dynamicTree.update(t_diff); //包围盒检测 /// update worldsessions for existing players for (m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter) { Player* player = m_mapRefIter->GetSource(); if (player && player->IsInWorld()) { //player->Update(t_diff); WorldSession* session = player->GetSession(); MapSessionFilter updater(session); session->Update(t_diff, updater); } } ... } ③处理人物的重生计时 /// process any due respawns if (_respawnCheckTimer <= t_diff) { ProcessRespawns(); UpdateSpawnGroupConditions(); _respawnCheckTimer = sWorld->getIntConfig(CONFIG_RESPAWN_MINCHECKINTERVALMS); } else _respawnCheckTimer -= t_diff; ④玩家战斗中技能释放、副本流程、人物、成就的更新 4)动态数据管理 (1)设计模式-访问者模式及代码表现形式 概念 ①提供一个访问者类,可以改变元素类的执行算法 ②传入不同的访问者,可以使用不同的执行算法解决的问题 稳定的数据结构和容易改变的操作耦合问题解决方法 在元素类型中提供对应不同访问者的接口目的 将数据结构和数据操作进行分离代码 T是算法,CONTAINER是数据结构 1)TypeContainer.h 有两种结构:双向链表和散列表,解决不同链表、不同散列表的差异 2)TypeContainerFunctions.h 解决双向链表和散列表之间的差异 3)TypeCOntainerVistor.h 解决对访问者的抽象,不同访问者实现不同的算法 template
inline void Map::Visit(Cell const& cell, TypeContainerVisitor
& visitor) { const uint32 x = cell.GridX(); const uint32 y = cell.GridY(); const uint32 cell_x = cell.CellX(); const uint32 cell_y = cell.CellY(); if (!cell.NoCreate() || IsGridLoaded(GridCoord(x, y))) { EnsureGridLoaded(cell); getNGrid(x, y)->VisitGrid(cell_x, cell_y, visitor); } } 通过下面这个函数将不同obj加入到不同的双向链表里面 1)不同双向链表: TypeMapContainer
i_container; TypeMapContainer
i_objects; 2)访问者算法加入不同链表的算法 template
class GridReference : public Reference
, OBJECT> { protected: void targetObjectBuildLink() override { // called from link() this->getTarget()->insertFirst(this); this->getTarget()->incSize(); } void targetObjectDestroyLink() override { // called from unlink() if (this->isValid()) this->getTarget()->decSize(); } void sourceObjectDestroyLink() override { // called from invalidate() this->getTarget()->decSize(); } public: GridReference() : Reference
, OBJECT>() { } ~GridReference() { this->unlink(); } GridReference* next() { return (GridReference*)Reference
, OBJECT>::next(); } }; 3)不同类型的访问者做不同处理,visit就是不同的算法 class TC_GAME_API ObjectGridLoader : public ObjectGridLoaderBase { friend class ObjectWorldLoader; public: ObjectGridLoader(NGridType& grid, Map* map, Cell const& cell) : ObjectGridLoaderBase(grid, map, cell) { } void Visit(GameObjectMapType &m); void Visit(CreatureMapType &m); void Visit(AreaTriggerMapType &m); void Visit(CorpseMapType &) const { } //尸体obj void Visit(DynamicObjectMapType&) const { } //动态物品,掉落装备等 void Visit(SceneObjectMapType&) const { } //场景对象 void Visit(ConversationMapType&) const { } //对话obj void LoadN(); }; 5)碰撞检测实现(BIH+AABB) 碰撞检测目标 对象模型的包围盒数据来源 vmap4extractor提取的场景信息(建筑、山脉、水体等)、角色、怪物、装备等3d模型信息逻辑流程 1)是否在视线范围内 2)碰撞检测,算命中位置(如不同楼层等高度信息) 3)获取地图信息怎么实现?(一句话:射线和包围盒的碰撞) ①插入的时候会平衡一次 ②然后就是定时200ms平衡一次实现代码 class TC_COMMON_API DynamicMapTree { DynTreeImpl *impl; public: DynamicMapTree(); ~DynamicMapTree(); bool isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, PhaseShift const& phaseShift) const; bool getIntersectionTime(G3D::Ray const& ray, G3D::Vector3 const& endPos, PhaseShift const& phaseShift, float& maxDist) const; bool getObjectHitPos(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist, PhaseShift const& phaseShift) const; //看层高 float getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const; bool getAreaInfo(float x, float y, float& z, PhaseShift const& phaseShift, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const; void getAreaAndLiquidData(float x, float y, float z, PhaseShift const& phaseShift, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const; //添加、删除、看是否存在 void insert(GameObjectModel const&); void remove(GameObjectModel const&); bool contains(GameObjectModel const&) const; //更新就是平衡 void balance(); void update(uint32 diff); //定时平衡,200ms平衡一次 }; 核心算法和数据结构 数据结构是BIH树,核心算法是AABB(轴对称边界盒算法,射线和包围盒相交的算法),BIH作为二叉树是为了快速进行流程,避免费时计算 如何实现BIH树? 1、构建BIH树 2、光线追踪算法AABB(AABB并不是稳定的结构,可能随时会有新obj进来)碰撞计算逻辑 1、计算包围盒(vmap数据中进行加载) 2、在一个grid中所有对象根据中轴线构建二叉树,左边为左子树,右边为右子树,判断节点方块与光线是否相交,若相交则不断递归下去,直到满足递归停止条件(递归深度64) 3、注意:每个节点都是子树对象包围盒的并集 4、射线就是行走路径 优化 ①初始时构建一次 ②定时构建: 1、200ms构建一次 2、如果BIH树发生改变才会重新构建 七、战斗模块 总体评价 分为skill和spell模块 1)技能模块 技能枚举 enum SpellRangeFlag { SPELL_RANGE_DEFAULT = 0, SPELL_RANGE_MELEE = 1, //melee,近战 SPELL_RANGE_RANGED = 2 //hunter range and ranged weapon,远程 }; ①技能信息类SpellInfo class TC_GAME_API SpellInfo { friend class SpellMgr; public: uint32 Id; SpellCategoryEntry const* CategoryEntry; uint32 Dispel; uint32 Mechanic; uint32 Attributes; ........ 八、MMO常用模块(任务、副本、商店等) 九、AI 文章记录在魔兽AI解析 十、游戏实体代码 代码细节 1)基类构造函数放在protected里面保证了该类的实例不能被直接创建,只能通过继承该类的子类来创建实例 1)trinitycore实体类介绍 ①Unit:表示游戏中的各种实体,例如玩家、NPC、怪物等。Unit是一个抽象的概念,包含了所有实体共有的属性和行为,例如位置、朝向、生命值、法力值、攻击力、防御力等。与Object、WorldObject和GameObject类不同的是,Unit类更加关注实体的战斗属性和行为,例如攻击、防御、技能等。 ②Creature:表示游戏中的怪物,是从Unit类继承而来的。Creature类包含了各种怪物特有的属性和行为,例如怪物类型、等级、掉落物品等。 ③Player:表示游戏中的玩家,也是从Unit类继承而来的。Player类包含了各种玩家特有的属性和行为,例如职业、技能、装备等。 ④Object类:是所有游戏实体类的基类,包含了所有实体共有的属性和行为,例如位置、朝向、生命值、法力值、攻击力、防御力等。与Unit、WorldObject和GameObject类不同的是,Object类更加关注实体的基本属性和行为,例如位置、朝向、生命值、法力值等。 ⑤WorldObject类:是从Object类继承而来的类,表示游戏中的所有可视实体,例如玩家、NPC、怪物、游戏对象等。与Unit、Object和GameObject类不同的是,WorldObject类更加关注实体的可视化属性和行为,例如模型、动画、光照等。 ⑥GameObject类:是从WorldObject类继承而来的类,表示游戏中的游戏对象,例如门、箱子、火堆等。与Unit、Object和WorldObject类不同的是,GameObject类更加关注实体的对象属性和行为,例如对象类型、状态、交互方式等。 2)分开介绍各实力类 (1)object类 十、背包模块 这里的代码解析我放到别的文章中去了 背包模块代码解析
上一篇
国外看香港
下一篇
阿里云 香港vps
相关文章
icp备案号忘记怎么办
如何使用 FinalShell 连接到 VMware 上的 Linux 虚拟机
bgp云服务器怎么样
倾向得分匹配只看这篇就够了
Linux防火墙firewalld不生效,无法拦截Docker映射端口
【Linux】进程间通信(万字详解)—— 匿名管道 - 命名管道 - System V - 共享内存
百旺信工业区怎么样
我的世界服务端vps怎么用
【黑客技术】LOIC —— 低轨道离子炮工具使用
香港云服务器租用推荐
服务器租用资讯
·广东云服务有限公司怎么样
·广东云服务器怎么样
·广东锐讯网络有限公司怎么样
·广东佛山的蜗牛怎么那么大
·广东单位电话主机号怎么填写
·管家婆 花生壳怎么用
·官网域名过期要怎么办
·官网邮箱一般怎么命名
·官网网站被篡改怎么办
服务器租用推荐
·美国服务器租用
·台湾服务器租用
·香港云服务器租用
·香港裸金属服务器
·香港高防服务器租用
·香港服务器租用特价
7*24H在线售后
高可用资源,安全稳定
1v1专属客服对接
无忧退款试用保障
德讯电讯股份有限公司
电话:00886-982-263-666
台湾总部:台北市中山区建国北路一段29号3楼
香港分公司:九龙弥敦道625号雅兰商业二期906室
服务器租用
香港服务器
日本服务器
台湾服务器
美国服务器
高防服务器购买
香港高防服务器出租
台湾高防服务器租赁
美国高防服务器DDos
云服务器
香港云服务器
台湾云服务器
美国云服务器
日本云服务器
行业新闻
香港服务器租用
服务器资讯
香港云服务器
台湾服务器租用
zblog博客
香港VPS
关于我们
机房介绍
联系我们
Copyright © 1997-2024 www.hkstack.com All rights reserved.