??xml version="1.0" encoding="utf-8" standalone="yes"?>
更新Q?/p>
更新方式Q?nbsp;
1.下蝲setup.bat文g直接替换原文Ӟ然后q行一ơsetup.bat:
setup.bat下蝲Q?nbsp;
链接Q?a target="_blank" style="text-decoration: none; box-sizing: border-box; color: #0c89cf;">http://pan.baidu.com/s/1mhPED6K
密码Q?6sx
2.下蝲完整vscode包:
完整vscode下蝲Q?nbsp;
癑ֺ云下载链接:http://pan.baidu.com/s/1dFt6uoL
密码Qis83
q是VSCode~写调试c/cppE序的便携式自动配置环境?/p>
首次使用双击setup.batq行自动配置Q以后每ơ打开VSCode.bat卛_?/strong>
setup.bat会向当前用户的文件夹内拷贝一些文ӞcpptoolQ用于配|,L(fng)保拥有够权限?/p>
内置的Project文g夹ؓ默认的项目文件夹Q其中预|了一个helloworld试E序?/p>
有疑问请联系Blackkitty
癑ֺ云下载链接:http://pan.baidu.com/s/1dFt6uoL
密码Qis83
逻辑层: cWorld实现了wow的WorldQ所有的逻辑处理
MaNGOS 下蝲Q编译,配置和运行的基本步骤 下蝲和安装msysgitQ用于代码管理我使用的是Git-1.6.5.1-preview20091022.exe
下蝲和安装tortoisegitQ用于代码管理我使用的是TortoiseGit-1.3.2.0-32bit.msi
使用git://github.com/mangos/mangos.gitQ从github提取mangos代码
采用Git GUI工具的Clone Existing RepositoryQ得?mangos代码Q我的是9560Q安装UDB参考这Q?nbsp;
使用git://github.com/scriptdev2/scriptdev2.gitQ从github提取scriptdev2代码
采用Git GUI工具的Clone Existing RepositoryQ得?scriptdev2代码.
~译mangos我用的是VC9,打开mangoswinmangosdVC90.slnq行构造,构造完成后Q会得到mangosbinWin32_Debug文g?nbsp;
~译scriptdev2我用的是VC9,打开mangoswinscriptdev2VC90.slnq行构造,构造完成后Q会得到scriptdev2binWin32_Debug文g夹也可参?nbsp;
pandore
拯mangossrcmangosd目录下的mangosd.conf.dist.in为mangosbinWin32_Debugmangosd.conf
拯mangossrcrealmd目录下的realmd.conf.dist.in为mangosbinWin32_Debugrealmd.conf
从http://www.wowtaiwan.com.tw/下蝲和安装台服WOWQƈ升到最新版本我使用的是台服WOW 3.3.2 build 11403
Q采用MaNGOS的工具ad从wow的MPQ中抽取mapQ得到的所有的map数据文gQ文件命名规范ؓmap_idQ?位) tileYQ?位) tileXQ?位).mapQ如文g名ؓ0002035.mapQ代表的是Azeroth(地图id?00Qtile坐标?35,20). 注:WOW客户端的Tile对应mangos中的gridQW(xu)OW客户端的Chunk对应mangos中的cell(1cell = 4 chunk)
按照常规程Q包括徏立数据库和配|服务器Q把服务器跑hQ用account create zzh1234567 zzh1234567 创徏一个̎P使用account set gmlevel zzh1234567 3讄U用?nbsp;
配置好客L(fng)后,q行W(xu)OWQ顺利登陆,呵呵
通过安装UDB来丰富场景FULL DB 9560 : HEREQ参考这Q在我安装DB9560的时候,发现Mangos在LoadCreatureAddons的时候,加蝲creature template addons出错QMangos只要求creature template addons?个字D,而creature template addons?个字D|现在只是单地跌LoadCreatureAddons的调?nbsp;
q行Mangos Q运行Mangos一节过期,是以前我针对国服3.1.3版本q行的安装配|) Q采用MaNGOS的工具ad从wow的MPQ中抽取mapQ得到的所有的map数据文gQ文件命名规范ؓmap_idQ?位) tileYQ?位) tileXQ?位).mapQ如文g名ؓ0002035.mapQ代表的是Azeroth(地图id?00Qtile坐标?35,20). 注:WOW客户端的Tile对应mangos中的gridQW(xu)OW客户端的Chunk对应mangos中的cell(1cell = 4 chunk)
配置好客L(fng)后,q行W(xu)OWQ顺利登陆,呵呵
Mangos代码阅读
Mangos?3个工E?nbsp;
使用?个外部工具库Q分别是Q?跨^台的|络通讯框架The ADAPTIVE Communication Environment (ACE)
压羃库zlib
Socket通信?C++ Sockets Library (使用在realmd工程中,和用在Mangosd工程中的RASocketQ负责处理Remote Administration其他地方没有使用到这个C++ Sockets Library Q发现在C++ Sockets Library的TcpSocket::Open中存在一个问题,在n = connect(s, ad, ad);语句执行后,如果n=-1QC++ Sockets Library会检是否ERR为WSAEWOULDBLOCKQ否则表C成功,但在动态库中用TcpSocket的时候,我发现n = connect(s, ad, ad);语句执行后,n=-1QERR会ؓ0Q这个时候连接也是成功了Q但TcpSocket::Open会当做不成功处理我发现这个问题,但没有时间去探究原因Q也许ƈ不是一个问?nbsp;
C++的ƈ行编E模板库Threading Building Blocks Qtbb ?tbbmallocQ?nbsp;
Mangos的实现分为:d服务器(realmdQ和世界服务器(mangosd+gameQrealmd和mangosq了Mangos公共库(sharedQ?nbsp;
工程shared
提供了通用功能Q包括了数据库的装c,实现了对MySql的访问,同样Q我们可以编写派生类来支持其他的数据?nbsp;
工程script
提供了脚本接口,q实C单的几个脚本Q封装ؓDLLQ提供给game使用Q具体可参考:MaNGOS脚本接口
通过使用不同的脚本DLL来替换share的这个DLL,可以让gameh更强的AIScriptDev2 是一个这L(fng)库ScriptDev2 is a replacement for the Script Library that comes with MaNGOS( http://www.getmangos.com ) written in C++ and is compatible with Windows and Linux. It provides scripts for NPCs, Boss events, and Items currently. On
工程mangosd
mangos是世界服务器的管理器Q负责初始化工作和启动世界服务器各层的线E,q些工作主要是由cMaster来实现具体是Q?使用三个数据库对象WorldDatabase和CharacterDatabase和loginDatabaseQ初始化三大数据库:World Database和Character Database和login DatabaseQƈ为每个数据库的访问都启动一个DB delay threads具体的数据库操作功能都是由Mangos公共库shared来提?nbsp;
调用sWorld.SetInitialWorldSettingsQ对Worldq行初始化,包括加蝲所有的游戏数据和初始化各种更新定时器和邮g定时器,q有些其他的初始化工作类World的成员函数SetInitialWorldSettings调用成员函数LoadConfigSettings解析mangosd.confQ解析后内容攑օuint32 m_configs[CONFIG_VALUE_COUNT]?nbsp;
加蝲的游戏数据有Q?nbsp;
DBC数据
Objects数据
Spells数据
Pooling数据
Game Event数据
loot数据
技能数?nbsp;
所有其他的游戏数据Q包括Waypoints和Trainers{等{?nbsp;
脚本数据
其他的初始化工作?
初始化MapManagerQ启动Map System
初始化BattlegroundsQ启动BattleGround System
初始化DailyQuestResetTime
初始化sGameEventMgrQStarting Game Event system
cMaster启动WorldRunnableQ开始游戏逻辑Heartbeat for the WorldQ由Master创徏Qƈ讄U程为最高优先
cMaster启动CliRunnableQCommand Line Interface handling threadQ由Master创徏CliRunnableq行时候会生成一个WorldDatabaseU程Q在接收到输入后会调用sWorld.QueueCliCommand把Cmd攑օ到World::cliCmdQueue?nbsp;
mangosd的线Ed有(1+3+1+1+1+2 +1 =10Q?0个线E?ȝEMaster
2个网l线EReactorRunnableQ可配置数目Q(|络层)
一个WorldU程Q逻辑层)
三个DBU程Q数据层Q?nbsp;
一个CLIU程Q输入层Q,q行时候会生成一个WorldDatabaseU程
一个RAU程Q管理层Q?nbsp;
一个freeze catcher U程Q可选)
工程g3dliteQ游戏逻辑层的底层?nbsp;
工程frameworkQ系l框?nbsp;
工程realm
负责登陆和选择游戏服务器,q行负蝲均衡用到了C++ Sockets Libraryq行d处理Q采用select I/O模型实现了Wow, Mangosd时的SRP6认证客户端作为它的clientq接到realm server认证和选择了mangos server断开 而mangos server和realm server则不q行q接Q只是通过数据库交互数据:mangos server把自q状态和拥有的角色数攑օ库中realm server会读取数据库中的q些信息来获知mangos server的状?数据库realm的realmlist表保存了realm的列?nbsp;
realm通过如下事g处理函数来负责登陆和选择游戏服务?nbsp;
const AuthHandler table[] =
{
{ AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge },
{ AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof },
{ AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge},
{ AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof },
{ REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList },
{ XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept },
{ XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume },
{ XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel }
}; d处理Q?nbsp;
userd到realm serverq行w䆾认证Qƈ选择d上哪个mangos serveruserd到mangos server后,不再和realm server交互
参考: Wow 服务器解?nbsp;
工程game
gameQ是Mangos的核心代码,|络层和逻辑层代?采用了ACE反应?Reactor)模式Q?nbsp;
|络层: WorldSocket Q负责网lIO,而类WorldSession负责逻辑处理WorldSocket和W(xu)orldSession分别在独立的U程ReactorRunnable和W(xu)orldRunnable中运行,使用WorldSession中的消息队列_recvQueue来进行数据缓冲在WorldSocket接收到网咯输入后Q会调用m_Session->QueuePacket (new_pct);把网l包攑օWorldSession的_recvQueue所以,可以看到WorldSocket 是Mangos game的网l层Q而W(xu)orldSession是逻辑处理层WorldSocketMgr是网l层的一个管理器Q它负责指派W(wng)orldSocket归哪个ReactorRunnable理QMangos可创建多个ReactorRunnableQ缺省是2个)
WorldSocketMgrQManages all sockets connected to peers and network threadsQ管理所有的q接WorldSocketWorldSocketMgr的WorldSocketMgr::StartNetwork?085Q缺省)端口q行侦听逻辑处理的@环是在World::Update中@环处理包括:
h更新定时?nbsp;
h游戏定时器和处理游戏关闭
处理日常d
处理拍卖
hSessionsWorld::UpdateSessions会调用所有WorldSession的WorldSession::Update在WorldSession::Update中进行逻辑处理
处理天气
huptime table
hObjectsQ包括mapsQtransportQcreaturesQ,Q,
h所有running battlegrounds
hSqlResultQueue, 逻辑层和数据层是通过Queue来进行异步操作的Q用了AsyncPQuery和SqlResultQueueQ?nbsp;
处理怽U除
处理游戏事g
处理 Move all creatures with "delayed move" and remove and delete all objects with "delayed remove"
处理InstanceSaveManager的刷?nbsp;
调用World::ProcessCliCommandsQ处理CLI从cliCmdQueue取得cmdq行解析执行所有有效的CmdQ都可以在ChatHandler::getCommandTable中找?nbsp;
cWorldSessionQ?cWorldSession负责逻辑处理
void WorldSession::SendPacket(WorldPacket const* packet) 负责发包l客L(fng)Q直接发包,没有输出~冲队列
在WorldSession::Update中进行逻辑处理World::UpdateSessions会调用所有WorldSession的WorldSession::Update
执行语句OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];得到opHandle
Ҏ(gu)得到的opHandleQ执?this->*opHandle.handler)(*packet);
WorldSession::HandlePlayerLogin处理玩家登陆游戏
构徏Player
Player::LoadFromDB从数据库中加载玩家数据在Player::LoadFromDB中会调用SetMap(MapManager::Instance().CreateMap(GetMapId() , this));加蝲当前player所在的map
Player::SetPosition在Playerq动的时候,改变位置Q保存处理夸?nbsp;
cMap实现了一个state machineQ采用state patternl织了Gid?个state objectQInvalidStateQActiveStateQIdleStateQRemovalState
game中的理器有Q?ObjectMgr
mMangosStringLocaleMap 兌到mangos_string table
m_scriptNames 兌到tables: creature_template;gameobject_template;item_templat e;areatrigger_scripts;instance_template
mCreatureLocaleMap 兌到l(f)ocales_creature table
mGameObjectLocaleMap兌到l(f)ocales_gameobject table
mItemLocaleMap兌到l(f)ocales_item table
mQuestLocaleMap –> locales_quest
mNpcTextLocaleMap –> locales_npc_text
mPageTextLocaleMap –> locales_page_text
mGossipMenuItemsLocaleMap –> locales_gossip_menu_option
mPointOfInterestLocaleMap –> locales_points_of_interest
…
对象cd?nbsp;
对象的类层次如下Q所有的Object都由O(jin)bjectMgrq行理ObjectMgr以GUID方式Q管理了charactersQcreatureQitem_instanceQgameobjectQauctionhouseQmailQitem_textQcorpseQarena_teamQcharacter_equipmentsets
Player状?nbsp;
/// Player state
enum SessionStatus
{
STATUS_AUTHED = 0, ///< Player authenticated (_player==NULL, m_playerRecentlyLogout = false or will be reset before handler call, m_GUID have garbage)
STATUS_LOGGEDIN, ///< Player in game (_player!=NULL, m_GUID == _player->GetGUID(), inWorld())
STATUS_TRANSFER, ///< Player transferring to another map (_player!=NULL, m_GUID == _player->GetGUID(), !inWorld())
STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, ///< _player!= NULL or _player==NULL && m_playerRecentlyLogout, m_GUID store last _player guid)
STATUS_NEVER ///< Opcode not accepted from client (deprecated or server side on
};
生物状?nbsp;
enum DeathState
{
ALIVE = 0,
JUST_DIED = 1,
CORPSE = 2,
DEAD = 3,
JUST_ALIVED = 4,
DEAD_FALLING= 5
};
玩家登陆
服务器端在连接打开后,会发SMSG_AUTH_CHALLENGE到客L(fng)客户端从服务器端发送回来的U子?SRP6 数据中生随机种子,生成 SHA1 字符Ԍ用这些数据生?CMSG_AUITH_SESSION 数据包,发送给服务端这个过E是没有l过加密?nbsp;
客户端发送SMSG_AUTH_SESSION到服务器
服务器处理SMSG_AUTH_SESSION
服务器发送SMSG_AUTH_RESPONSEl客L(fng)
服务器发送SMSG_ADDON_INFOl客L(fng)
服务器发送SMSG_CLIENTCACHE_VERSIONl客L(fng)
服务器发送SMSG_TUTORIAL_FLAGSl客L(fng)
packetl构 SMSG_AUTH_SESSION 是client packet有一个头部(ClientPktHeaderQ,后面是数据块
SMSG_AUTH_RESPONSE 是server packet有一个头部(ServicePktHeaderQ,后面是数据块
SMSG_AUTH_RESPONSE 的包l织
SMSG_AUTH_RESPONSE 的opcode?1EEQByteBuffer大小? + 4 + 1 + 4 + 1=11一个SMSG_AUTH_RESPONSE 的数据如下: 在构造了SMSG_AUTH_RESPONSE packet后,W(xu)orldSocket::SendPacket会根据SMSG_AUTH_RESPONSE packet构造出一个ServerPktHeaderQƈ对ServerPktHeader中的数据headerq行加密发送加密采用m_Crypt.EncryptSend ((uint8*)header.header, header.getHeaderLength()); WorldSocket::handle_input_header会对从客L(fng)接收来的数据q行解密Q解密采用m_Crypt.DecryptRecv ((uint8*) m_Header.rd_ptr (), sizeof (ClientPktHeader));
角色枚D 玩家M服务器后Q从客户端发送SMSG_CHAR_ENUM到服务器
在服务器?nbsp;
Ҏ(gu){ "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode }Q服务器会调用WorldSession::HandleCharEnumOpcode
WorldSession::HandleCharEnumOpcode会调用CharacterDatabase.AsyncPQueryQ进行异步查询后Q调用CharacterHandler::HandleCharEnumCallback
CharacterHandler::HandleCharEnumCallback会回头调用session->HandleCharEnum(result);
WorldSession::HandleCharEnumҎ(gu)characters数据库的查询l果Q调用Player::BuildEnumDataQ加载角色数据,构造SMSG_CHAR_ENUMq回包,然后发送回客户?nbsp;
角色创徏
角色的初始化装备在CharStartOutfit.dbc
角色的创建和选择的设|都?ChrRaces.dbc
角色的创建属性都在PlayercreateinfoQ包括出生地和出生属?nbsp;
playercreateinfo_item表是创徏一个新人物Ӟ人物默认带的所有Item的表
playercreateinfo_spell表是创徏一个新人物Ӟ人物默认带的所有Spell的表
角色删除
# MaNGOS Configuration file 服务器配|文件中文说?br style="box-sizing: border-box;" />ConfVersion=2007071001 # RealmID must match the realmlist (国度ID 必牒?攘斜砝锩娴南? RealmID = 1 # 0 NORMAL 1 PVP 4 NORMAL 6 RP 8 RPPVP(服务器类? GameType = 1 # 扩展柚每 ?# 0 不检查扩展地?不允许创建新U族,忽略账号的扩展设|? # 默认: 1 (如果客户端支持扩展且账号拥有扩展权限,卛_怋用新U族及访问新地图.) Expansion = 1 #==================================服务端添加的参数=========================================================================== #世界聊天消费(默认?G/? sjxf=10000 #初始人物金币Q以分ؓ单位. # 默认: 8 mymoney = 1000000 # 自动公告旉间隔 1=1U?br style="box-sizing: border-box;" />AutoBroadcastInterval=10 #初始怪物怽停留旉 #单位/U?nbsp; # 默认: 60 MyCropseDelay = 60 #人物复活虚弱旉 #默认: 1000 Playerdietime = 1000 #初始出生人物{ # 默认: 1 LevelFirst = 1 #加血技能治疗倍数 aurahealing = 5 #法术技能伤宛_数 tmpDamage = 5 #物理技能伤宛_数(数字别改的太大了) pdaDamage = 2 #猎h闪避率设|?数字大闪避率越? Rate.Hunter_Max.Dodge=31.4 #盗贼闪避率设|?数字大闪避率越? Rate.Roguer_Max.Dodge=19.5 #其他职业闪避率设|?数字大闪避率越? Rate.Else_Max.Dodge=27 #==================================服务端添加的参数=========================================================================== # 数据目录讄?br style="box-sizing: border-box;" /># 重要说明Q数据目录需要放在引号里面,因ؓ字符串可能包含空?br style="box-sizing: border-box;" /># DataDir = "@MANGOSD_DATA@" //q个是默认目?br style="box-sizing: border-box;" />DataDir = "./" # Logs directory setting. # Important: Logs dir must exists, or all logs be disable # Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be stored in current directory for run program. LogsDir = "" # 世界服务器的数据库连接设|?br style="box-sizing: border-box;" /># 格式Q主机地址(域名或IPQ?端口;用户?密码;数据库名U?br style="box-sizing: border-box;" /># .;somenumber;username;password;database - use named pipes at Windows # Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini # .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux # Unix sockets: experimental, not tested LoginDatabaseInfo = "127.0.0.1;3306;root;netspace;realmd" WorldDatabaseInfo = "127.0.0.1;3306;root;netspace;mangos" # 讄最高ping数据库的旉间隔(分钟) MaxPingTime = 30 # DBC 语言讄 #8 p #4 韩语 #3 法语 #3 徯 #4 中文 #5 台湾J体 #6 西班牙语 #7 俄语 #8 未知 # 8 = Unknown # 9 = Unknown # 10 = Unknown # 11 = Unknown # 12 = Unknown # 13 = Unknown # 14 = Unknown # 15 = Unknown # 255 = 自动?(默认) DBC.Locale = 255 # 启用GM命o记录-所有的SQL代码都将被记录在日记文g?br style="box-sizing: border-box;" /># All commands are written to a file: YYYY-MM-DD_logSQL.sql # If a new day starts (00:00:00) then a new file is created - the old # file will not be deleted. # 0 - 不记?br style="box-sizing: border-box;" /># 1 - 记录 LogSQL = 1 # 服务器控制台记录昄的?br style="box-sizing: border-box;" /># 0 = 最? 1 = 基础和错? 2 = 详细; 3 = 完全或侦?br style="box-sizing: border-box;" /># 默认: 0 # 推荐: 1 LogLevel = 0 # 记录文g 的名?br style="box-sizing: border-box;" /># 文g名ؓI?则不创徏记录文g,? LogFile = # 默认: "" LogFile = "Server.log" # Logfile with timestamp of server start in name # Default: 0 - no timestamp in name # 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext LogTimestamp = 0 # 记录文g的记录?br style="box-sizing: border-box;" /># 0 = 最? 1 = 基础和错? 2 = 详细; 3 = 完全或侦?br style="box-sizing: border-box;" /># 默认: 0 LogFileLevel = 0 # Log filters # 0 (default) - include in log if log level permit, 1 - not include with any log level LogFilter_TransportMoves = 0 LogFilter_CreatureMoves = 0 LogFilter_VisibilityChanges = 0 # 控制C息的颜色 (格式: "正常颜色 详情颜色 debug颜色 错误颜色) # 颜色: 0-黑色, 1-U? 2-l? 3-? 4-? 5-品红, 6-青绿, 7-灰色, # 8-? 9-淡红, 10-淡绿, 11-淡蓝, 12-淡品U? 13-淡青l? 14-白色 # 默认: "" 无颜?白色) # 例如: "13 7 11 9" LogColors = "13 7 11 9" # Packet logging file for the worldserver. # Default: "" WorldLogFile = "world.log" # 记录数据库错误的文g?br style="box-sizing: border-box;" /># 默认: "" DBErrorLogFile = "DBErrors.log" # 记录GM命o使用情况?记录文g?br style="box-sizing: border-box;" /># 默认: "" (止) 允许?例如: "GMcommand.log" GmLogFile = "" # Log file of RA commands, "" for disable # Default: "Ra.log" RaLogFile = "" # 在多U程pȝ 使用U程MASK(只在Windowspȝ下? # 默认: 0 (操作pȝ来选择) # 举例: 数字 UseProcessors = 80 # q程优先权设|?只在Windowspȝ下? # 0 (正常优先? # 默认: 1 (高优? ProcessPriority = 1 #发送到客户端的更新数据包的压羃U别(1?) # 默认: 1 (速度?不压~? # 9 (最好的压羃) Compression = 1 # 除GM之外 游戏最大在U玩家数限制 # 默认: 100 PlayerLimit = 100 # 玩家获得l验能升到的最高等U?必须?1 ?255). # 不徏议修?用默认的 60 过60 可能影响游戏q # 默认: 60 MaxPlayerLevel = 70 # 天气pȝ开?br style="box-sizing: border-box;" /># 默认: 1 (开) # 0 (? ActivateWeather = 1 # 是否忽略q入副本的等U需?br style="box-sizing: border-box;" /># 1 (true) # 默认: 0 (? IgnoreATLevelRequirement = 0 # 玩家最多可以学?商业技?br style="box-sizing: border-box;" /># 默认: 2 # 最? 9 MaxPrimaryTradeSkill = 2 # 建立公会所需的最玩家签名个?(0..9). # 默认: 9 MinPetitionSigns = 9 # 队成员在生物死?获得l验?最大距?同怪物的距? # 默认: 74 MaxGroupXPDistance = 74 # 队成员在生物死?获得l验?最大等U差(同怪物的等U? # 默认: 10 MaxGroupXPLevelDiff = 10 # 是否q行?个帐?建立?个不同阵营的角色 GM号ؓ始终?允许 # 默认: 0 (不允? # 1 (允许) AllowTwoSide.Accounts = 0 # 是否允许 不同阵营间的 聊天 频道聊天 l队 交易 # 默认: 0 (不允? # 1 (允许) AllowTwoSide.Interaction.Chat = 0 AllowTwoSide.Interaction.Channel = 0 AllowTwoSide.Interaction.Group = 0 AllowTwoSide.Interaction.Guild = 0 AllowTwoSide.Interaction.Trade = 0 # 是否?在线玩家列表 里显C敌寚w营玩?br style="box-sizing: border-box;" /># 默认: 0 (不允? # 1 (允许) AllowTwoSide.WhoList = 0 # 防刷屏开?多少条违规信息激zM?br style="box-sizing: border-box;" /># 0 (为关闭防刷屏) # 默认: 10 ChatFlood.MessageCount = 10 # 防刷屏开?多少U间隔开始计ؓq规信息 # 默认: 1 (U? ChatFlood.MessageDelay = 1 # 防刷屏开?言旉. # 默认: 10 (U? ChatFlood.MuteTime = 10 # GM默认是否接受玩家的?zhn)?zhn)话. # 默认: 0 (false) # 1 (true) GM.WhisperingTo = 0 # 当GM讄为可见时 是否在玩家列表显CGM. # 默认: 0 (false) # 1 (true) GM.InGMList = 0 # 是否昄GM名单 (if visible). # 默认: 0 (false) # 1 (true) GM.InWhoList = 0 # GM模式在登陆时状?br style="box-sizing: border-box;" /># 0 (L? # 1 (L开) # 默认: 2 (上次d时状? GM.LoginState = 2 # 如果打开 则在GM LOG里记录GM的交易和交易信息 # 0 (不记? # 默认: 1 (记录) GM.LogTrade = 1 # 团队可见模式 # 默认: 0-标准讄Q只有同一个团队的队友才可?00%侦测隐Ş玩家 # 1-只有同一个小队的队友才可?00%侦测隐Ş玩家 # 2-同一阵营的队友可?00%侦测隐Ş玩家 Visibility.GroupMode = 0 # 不同的游戏物体之间的可见?nbsp; # 最大设|? ~ 166 # 最设|以物体为准 # 默认: 66 (单元) # # Min limit is max aggro radius (45) * Rate.Creature.Aggro Visibility.Distance.Creature = 66 Visibility.Distance.Player = 66 # gameobject, dynobject, bodies, corpses, bones # Min limit is iteraction distance (5) Visibility.Distance.Object = 66 # visible distance for player in flight # Min limit is 0 (not show any objects) Visibility.Distance.InFlight = 66 # Visibility grey distance for creatures/players (fast changing obects) # addition to appropriate object type Visibility.Distance.* use in case visibility removing to object (except corpse around distences) # If ?is distance and G is grey distance then object make visible if distance to it <= D but make non visible if distance > D+G # Default: 1 yard Visibility.Distance.Grey.Unit = 1 # Visibility grey distance for dynobjects/gameobjects/corpses/creature bodies # # Default: 10 yards Visibility.Distance.Grey.Object = 10 # 如果邮寄物品延时多久收到Q? # 默认: 3600 U?(1 hour) MailDeliveryDelay = 3600 # 每日消息。当玩家q入游戏的时候显C在聊天H口的信息?br style="box-sizing: border-box;" />Motd = "Welcome to the Massive Network Game Object Server." # Health and power regeneration and rage income from damage. Rate.Health = 1; Rate.Mana = 1; Rate.Rage.Income = 1; Rate.Rage.Loss = 1; Rate.Focus = 1; # 物品的掉率倍数 #poor,白色Q?br style="box-sizing: border-box;" />#common,普通; #uncommon,|见? #rare,贵重的; #Epic,史诗; #Legendary,传说; #uest,d> # 默认: 1 # Rate.Drop.Items = 1 Rate.Drop.Items.Quality.Poor = 1 Rate.Drop.Items.Quality.Common = 1 Rate.Drop.Items.Quality.Uncommon = 1 Rate.Drop.Items.Quality.Rare = 1 Rate.Drop.Items.Quality.Epic = 1 Rate.Drop.Items.Quality.Legendary = 1 Rate.Drop.Items.Quest = 1 Rate.Drop.Money = 1 # 杀?d,探烦地图 获得l验 乘以的倍数 # 默认: 1 Rate.XP.Kill = 20 Rate.XP.Quest = 30 Rate.XP.Explore = 10 # 普?_英,E有精?BOSS,E有普通?的伤?乘以的倍数 # 例如: 1.4 是 增加0.4倍攻M?br style="box-sizing: border-box;" />Rate.Creature.Normal.Damage = 1 Rate.Creature.Elite.Elite.Damage = 1 Rate.Creature.Elite.RAREELITE.Damage = 1 Rate.Creature.Elite.WORLDBOSS.Damage = 1 Rate.Creature.Elite.RARE.Damage = 1 # 普?_英,E有精?BOSS,E有普通?的血?乘以的倍数 # 例如: 1.4 是 增加0.4倍攻击血?br style="box-sizing: border-box;" />Rate.Creature.Normal.HP = 1 Rate.Creature.Elite.Elite.HP = 1 Rate.Creature.Elite.RAREELITE.HP = 1 Rate.Creature.Elite.WORLDBOSS.HP = 1 Rate.Creature.Elite.RARE.HP = 1 #仇恨pLQ默?.1fQ即有超q第一仇恨者造成伤害110%者就转变d对象?br style="box-sizing: border-box;" />#注意Q必ȝ到数点后1?br style="box-sizing: border-box;" /># 默认: 1.1f AggroThreat = 1.1f # _֊条增长倍数 (1 - normal, 2 - double rate, 0.5 - half rate, etc) from standard values # 游戏?br style="box-sizing: border-box;" />Rate.Rest.InGame = 1 # 在旅馆下U时 Rate.Rest.Offline.InTavernOrCity = 1 # 在野外下U时 Rate.Rest.Offline.InWilderness = 1 # IZ跌落伤害倍数 Rate.Damage.Fall = 1 # 拍卖 倍数 # Rate.Auction.Time (拍卖旉倍率),Rate.Auction.Deposit(拍卖押金),Rate.Auction.Cut(拍卖上限) Rate.Auction.Time = 1 Rate.Auction.Deposit = 1 Rate.Auction.Cut = 1 # 矿物 倍数 #Rate.Mining.Next (采矿的几率倍数),Rate.Mining.Amount (产生矿最大最的倍数) Rate.Mining.Amount = 1 Rate.Mining.Next = 1 # 天赋点的升倍率 # 默认: 1 Rate.Talent = 1 # 保存h旉 当生物死 当物体被打开或?br style="box-sizing: border-box;" /># 0 (保存?物体的刷新时间在|格卸蝲的时? # 默认: 1 (不在|格卸蝲的时候保存h/物体的刷新时? SaveRespawnTimeImmediately = 1 # 技能熟l度提升几率(0..100) # 默认: 100-75-25-0 SkillChance.Orange = 100 SkillChance.Yellow = 75 SkillChance.Green = 25 SkillChance.Grey = 0 # 怪物自动d的范围乘以的倍数 或?关闭自动d # 0 - 关闭(0%) # 默认: 1 - 乘以100% # 1.5 - 乘以150% Rate.Creature.Aggro = 1 # 控制台开?br style="box-sizing: border-box;" /># 0 - ?br style="box-sizing: border-box;" /># 默认: 1 - 开 Console.Enable = 1 # q程控制台开?br style="box-sizing: border-box;" /># 默认: 0 - ?br style="box-sizing: border-box;" /># 1 - 开 Ra.Enable = 0 # 默认q程控制IP地址,0.0.0.0为所有IP皆可. Ra.IP = 0.0.0.0 # 默认q程控制台端?br style="box-sizing: border-box;" />Ra.Port = 3443 # q程控制台连接到服务器所需要的GM{Q默认ؓ3Q管理员Q?br style="box-sizing: border-box;" />Ra.MinLevel = 3 # t出用户Q如果他输入了错误的密码 Q仅限远E控制台Q?br style="box-sizing: border-box;" />Ra.Secure = 1 # 最大速度限制倍率 # 默认: 2 如果?则关闭检查加?br style="box-sizing: border-box;" />MaxOverspeedPings = 2 # 卸蝲Grids (如果里的内存够大,可以用,提高玩家W二ơ经q新Grids时候的速度) # P.S: Grids是地图上刷出来的东?玩家l过一个地?׃加蝲该地方的环境,d的时?卸载该地方的环?br style="box-sizing: border-box;" /># 默认: 1 ( 卸蝲 grids) 0 ( 不卸?grids) GridUnload = 1; # 以下所有的旉讄都以毫秒为单位?br style="box-sizing: border-box;" /># 默认端口选择旉 SocketSelectTime = 10000 # 默认地图|格清理延迟 GridCleanUpDelay = 300000 # 默认地图更新间隔 MapUpdateInterval = 100 # 默认天气更新间隔 ChangeWeatherInterval = 600000 # 默认玩家数据保存间隔 PlayerSaveInterval = 900000 # 默认世界服务器端?mangosd.exe 的端口) WorldServerPort = 8085 # 在mangos启动完毕后蜂鸣一?通常只在Unix nuxpȝ下工? # 默认: 1 BeepAtStart = 1 # 打开/关闭 VMmap 对视U和高度的推支?br style="box-sizing: border-box;" /># Default: 1 (true) # : 0 (false) vmap.enableLOS = 1 vmap.enableHeight = 1 # 不?VMap功能的地图ID # 地图ID之间?','分割 # 如果有多个地图ID使用 "号包?br style="box-sizing: border-box;" />#vmap.ignoreMapIds = "369,0,1,530" #DeeprunTram 没有包含在地图中 vmap.ignoreMapIds = "369" # 不进行视U推的技?br style="box-sizing: border-box;" /># 技能之间?','分割 vmap.ignoreSpellIds = "7720" |
The navigation mesh query is the most important class to understand since most navigation clients will interact with the query rather than the navigation mesh itself. The mesh contains the data, but the query provides almost all of the features necessary for pathfinding.
用户和navigation mesh query(Navmesh查询?打交道的ơ数比Navmes本n多的多。网格包含数据,但是查询器提供了几乎全部的寻路特性?/p>
Core Class: NavmeshQuery
核心c:NavmeshQuery
Query features fall into two general categories: Pathfinding and local search.
查询器的Ҏ(gu)包括两个大的方面:寻\和局部搜索?/span>
Pathfinding involves standard A* and Dijkstra searches that find the best path(s) between two points. Paths are made up of a list polygon references that represent a polygon corridor from the start to the end position. Path straightening is used to convert the path into a list of waypoints. (I.e. String pulling.)
寻\使用标准的A*和Dijkstra法Q用于找Z点之间最好的路径(可能不止一?。Path(路径)是由一lPolygon的引?1)l成数据Q从开始点到结束点。\径矫正是一个Path数据转ؓ一l\Ҏ(gu)?即String pulling(l_拉直))(2)?/span>
The local search features offer various methods for locating polygons and points on polygons, and for querying the local environment. I.e. Raycasting, finding the distance to the nearest wall, etc.
局部搜索功能提供多U方式进行多边Ş和多边Ş上的点的定位Q以及查询局部的一些环境信息。比如射U查询、计离最q的墙的距离之类的?/span>
Many of the query methods require a NavmeshQueryFilter. Filters define area traversal costs as well as flags used for including/excluding polygons and off-mesh connections from results.
许多查询Ҏ(gu)要求一个NavmeshQueryFilter(查询qo?。过滤器定义了Polygon和off-mesh connections的穿代P代h(hun)值可以参与启发式的计,用来军_是否在最l\径里包含/排除某个Polygon或off-mesh connections?/span>
The best way to understand the query class is to play around with it. The Sample Pack includes the Query Explorer demo that permits experimentation with all of the main query features.
理解查询器的最好办法就是用一用。【Sample Pack(CZ?】里的【Query Explorer(查询演示)】demo展示了查询器一些主要的Ҏ(gu)?/span>
Common Operations
通用操作
This section contains some simple examples of common query operations.
Finding a Point in the Navigation Mesh
You can't do much without first getting a valid point on the navigation mesh. So the first step is to find one.
GetNearestPoint(Vector3, Vector3, NavmeshQueryFilter, NavmeshPoint)
本节是例?/span>
查询一个在Navmesh上的?/span>
如果你没有一个Navmesh上的起始点的话,你能做的不多。所以第一部就是找一个点?/span>
GetNearestPoint(Vector3, Vector3, NavmeshQueryFilter, NavmeshPoint)函数提供此功能?/span>
CopyC#
// Where 'query' is a NavmeshQuery object and 'filter' is a NavmeshQueryFilter object.
// 'position' is a Vector3 indicating the world position of the client.
// 'query'是一?NavmeshQuery对象Q?filter'是一个NavmeshQueryFilter对象?/span>
// 'position' 是一个Vector3对象Qgؓ角色的世界坐标?/span>
NavmeshPoint result;
Vector3 extents = new Vector3(1, 1, 1); // Keep this to the minimum extents practical. // 范围小好?/span>
NavStatus status = query.GetNearestPoly(position, extents, filter
, out result);
if (result.polyRef == Navmesh.NullPoly)
{
// Handle error. Could not find a result.
// The status can be checked to see if there was an error. If not, then
// the cause is that the search extents did not overlap any polygons.
// 错误处理。找不到l果?/span>
// 可以查状态看看是什么问题。如果没有问题,说明指定范围里不包含多边形?/span>
}
// Use the result point, which includes a vector point and the reference of
// the polygon that contains the point.
//使用l果炏V包括一个Vector3的点和包含这个点的Polygon的引用?/span>
Basic Pathfinding
Even if you are planning to use PathCorridor or CrowdManager, you'll always need to do long distance planning using the basic NavmeshQuery features. First, get a path, then optionally straighten it.
基础的寻?/span>
即你打用pathcorridor或crowdmanager,你也会需要NavmeshQuery的功能来完成一些长距离路径规划。第一Q获取一条\径,然后选择性的弄直?3)?/span>
CopyC#
// Where 'query' is a NavmeshQuery object and 'filter' is a NavmeshQueryFilter object.
// 'start' and 'end' are NavmeshPoints known to be on the navigation mesh.
// 'query'是一?NavmeshQuery对象Q?filter'是一个NavmeshQueryFilter对象;
// 'start' ?'end' 是已知的在Navmesh上的?
int pathCount;
// The path will be a list of polygon references.
// path是一lpolygon的引?
uint[] path = new uint[100]; // Size for maximum allowed path length. // 路径的最大长?
NavStatus status;
if (start.polyRef == end.polyRef)
{
// No need to do any planning.
// 开始点和结束点在同一个多边Ş内,不需要进行\径规?
pathCount = 1;
path[0] = start.polyRef;
}
else
{
status = query.FindPath(start, end, filter, path
, out pathCount);
if (NavUtil.Failed(status) || path.pathCount == 0)
{
// Handle pathfinding failure.
// 处理寻\p|;
}
else if (end.polyRef != path[pathCount - 1])
{
// Handle a partial path.
// The query either could not reach the end point,
// or the path buffer was too small to hold the
// entire path. (A check of 'status' will reveal if
// the buffer was too small.)
// 处理只有一部分路径的情?
// 可能是结束点不可?
// 或者\径的buffer长度太小Q装不下整条路径;
// 如果是buffer太小Q可以检查state;
}
}
// If you need to straighten the path...
// 如果你需要拉直\?
const int MaxStraightPath = 4; // Just getting the first 4 waypoints. // 只处理前4个\?
int wpCount;
// The waypoints.
// 路点列表;
Vector3[] wpPoints = new Vecotr3[MaxStraightPath];
// A list of polygon references. (The polygon being entered at each waypoint.)
// 一个多边Ş引用列表;(路点是多边Ş的入口点)
uint[] wpPath = new uint[MaxStraightPath];
// The type of each waypoint. (Start, end, off-mesh connection.)
// 每一个\点的cd信息.(开始点Q结束点, q接);
WaypointFlag[] wpFlags = new WaypointFlag[MaxStraightPath];
status = query.GetStraightPath(start.point
, goal.point
, path
, 0 // The index of the start of the path. // 路径的开始点;
, pathCount // The length of the path. // 路径的长?
, wpPoints
, wpFlags
, wpPath
, out wpCount);
if (NavUtil.Failed(status) || wpCount == 0)
{
// Handle the failure. There should always be at least one waypoint
// (the goal) for a valid point/path combination,
// 处理p|。应该L存在一个点(目标?用于路径合ƈ.
}
// Use the path and waypoints.
// 使用路径和\?
(1)可以理解为句柄,或烦引?/span>
(2)Path上每个多边Ş中心之间的连U一般不会是直线Q\径如果有拐角也会造成一些美观上的问题,q个时候需要用特定的Ҏ(gu)\径变得尽量笔_好像将一根子拉直?/span>
]]>