TrinityCore MMORPG服务器设计分析

本文是通过TrinityCore研究从而对MMORPG服务器设计分析。

网络字节序

ByteBuffer是字节(unsigned char类型)处理,没有大小端处理。在网络通信应用程序上,这种是经常有的,网络是通过字节发送。

消息包格式:包头+包类型+包体

包头rc4加密

登录认证是(srp6)安全远程密码第六版协议,包类型是占一字节。

游戏中,包类型占1.5字节。

1、封包

重载&operator<<
按顺序把数据封包

2、解包

重载&operator>>
按顺序把数据解出

消息包处理

网络是采用boost asio

1、发送

这里需要注意,在这个执行,在多线程里面操作加锁

std::unique_lock<std::mutex> guard(_writeLock);

boost::asio的发送函数:_socket.async_write_some

1.1 登录认证的发送

void AuthSession::SendPacket(ByteBuffer& packet)
{
    if (!IsOpen())
        return;

    if (!packet.empty())
    {
        MessageBuffer buffer;
        buffer.Write(packet.contents(), packet.size());

        std::unique_lock<std::mutex> guard(_writeLock);

        QueuePacket(std::move(buffer), guard);
    }
}

 2.2在游戏中发送

void WorldSocket::SendPacket(WorldPacket const& packet)
{
    if (!IsOpen())
        return;

    if (sPacketLog->CanLogPacket())
        sPacketLog->LogPacket(packet, SERVER_TO_CLIENT, GetRemoteIpAddress(), GetRemotePort());

    ServerPktHeader header(packet.size() + 2, packet.GetOpcode());

    std::unique_lock<std::mutex> guard(_writeLock);

    _authCrypt.EncryptSend(header.header, header.getHeaderLength());

#ifndef TC_SOCKET_USE_IOCP
    if (_writeQueue.empty() && _writeBuffer.GetRemainingSpace() >= header.getHeaderLength() + packet.size())
    {
        _writeBuffer.Write(header.header, header.getHeaderLength());
        if (!packet.empty())
            _writeBuffer.Write(packet.contents(), packet.size());
    }
    else
#endif
    {
        MessageBuffer buffer(header.getHeaderLength() + packet.size());
        buffer.Write(header.header, header.getHeaderLength());
        if (!packet.empty())
            buffer.Write(packet.contents(), packet.size());

        QueuePacket(std::move(buffer), guard);
    }
}

2、接收

接收函数_socket.async_read_some

处理已收到数据包MessageBuffer& packet = GetReadBuffer();

登录认证接收处理:void WorldSocket::ReadHandler()

游戏过程处理:

void WorldSocket::ReadHandler()

bool WorldSocket::ReadHeaderHandler()

bool WorldSocket::ReadDataHandler()

流程

消息通过函数指针映射处理。

1、登录游戏

std::unordered_map<uint8, AuthHandler> const Handlers = AuthSession::InitHandlers();

2、认证通过后

void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)

内部把这次玩家会话添加 :

新建一个会话_worldSession = new WorldSession(id, shared_from_this(), AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter);

添加到世界:sWorld->AddSession(_worldSession);

判断是否有同个帐号登录,如果有,把它踢下线

2、全部会话处理:

void World::UpdateSessions(uint32 diff)
{
..
 for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
..

}

2、游戏过程中

extern OpcodeHandler opcodeTable[NUM_MSG_TYPES]

写在后面

TrinityCore常用了TCP通信,tcp通信也是存在心跳的,网络是异常退出(比如,任务管理器直接杀死游戏进程),tcp协议不会通知说我已经退出。如果是实时再线格斗类型游戏,建议常用UDP。TrinityCore大量使用c++ 0x11,有些地方,我也不是明白,如果有存在错误的地方也请指出。

mmorpg魔兽世界服务器框架TrinityCore构建

本文对TrinityCore 版本7.x | 3.3.5编译说明通用。

简介

TrinityCore 是c++实现MMORPG框架

来自MaNGOS,大型网络对象服务,随着时间的推移,该项目代码广泛的优化,改善和清理代码。

这是完全开源的,社区参与是高度鼓励

如果你有好的想法请访问网站github 库https://github.com/TrinityCore/TrinityCore,提出。

更多TrinityCore项目信息,请访问TrinityCore.org

要求

  • 平台:Linux, Windows or Mac>
  • cpu支持SSE2
  • Boost ≥ 1.49
  • MySQL ≥ 5.1.0
  • CMake ≥ 2.8.11.2 / 2.8.9 (Windows / Linux)
  • OpenSSL ≥ 1.0.0
  • GCC ≥ 4.7.2 (Linux only)
  • MS Visual Studio ≥ 12 (2013) (Windows only)
  • 按里面提示的软件进行安装:http://collab.kpsn.org/display/tc/Requirements现在windwos的

安装

本节只讨论windows 7系统安装

TrinityCore:https://github.com/TrinityCore/TrinityCore/releases

1、生成vs2013工程解决方案

  1. 下载名字ource code (zip)
  2. 打开cmake
  3. Where is the Source code: E:/SDK/TrinityCore-stable
  4. Where to build th binaries:E:/SDK/TrinityCore-stable/build
  5. 点击Configure 现在 vs2013,把TOOLS勾上,点击Generate生成TrinityCore.sln
  6. 编译解决方案

如果是64位系统需要手动去把mysql库,指向win32的,否则出现link 2019错误。

2、生成地图

  1. 安装好World of Warcraft – 3.3.5a (12340) – enUS (No Install),建议编译Release的版本,生成地图快
    可C:\TrinityCore\contrib 复制 “extractor.bat”及地图生成工具4个exe 放wow.exe同目录,(2 3 4 5步骤可跳过)
  2. 在Wow.exe同目录下一次点击mapextractor.exe
  3. mmaps_generator.exe
  4. vmap4extractor.exe
  5. vmap4assembler.exe
  6. 生成的dbc maps mmaps vmaps拷贝v到 authserver.exe worldserver.exe目录下

3、数据库安装

  1. 默认mysql安装,添加帐号:trinity,密码:trinity
  2. 数据库图形管理工具HeidiSQL或者SQLyog,推荐用SQLyog
  3. 工具->现在执行sql文件…sqlcreatecreate_mysql.sql
  4. 选择auth数据库 工具->现在执行sql文件…sqlbaseauth_database.sql
  5. characters数据库 同上面操作执行…sqlbasecharacter_database.sql
  6. world数据库 同上面操作执行…”TDB_full_*.sql。下载名字是TDB_full

4、运行

  1. authserver.conf.dist和worldserver.conf.dist 去掉dist
  2. 运行authserver.exe,再运行worldserver.exe
  3. worldserver窗口里创建游戏帐号:account create username password
  4. 修改游戏客户端DataenUSrealmlist.wtf内容为:set realmlist 127.0.0.1
  5. 运行wow登录。。

结束语

大概步骤是和Mangos构建是类似的,上面没说到是用了那个版本,自己下载数据库和源码版本一致。

最后来个截图,这图只是研究使用,无意对暴雪侵权,图:魔兽世界:巫妖王之怒3.35

wow 3.35