共计 2047 个字符,预计需要花费 6 分钟才能阅读完成。
我用 php 构建了魔兽世界服务器
-- 只为证明 php 是世界上最好的语言
作为一个魔兽老玩家,最近看着暴雪开了怀旧服,早已寂灭的心又开始躁动不安了,我正式入坑是网易接替九城那会,号称万年 TBC, 对于那个时代,用一句话表达就是“我站在暴风城的广场上,听着港口涛声,幻想着诺森德天气多么寒冷…”,你懂的~
那时候刚上大学, 对于涉世未深的我来说, 魔兽的差点让我变成网瘾少年,直到毕业步入社会,才慢慢淡绝了对魔兽的念想,但无论过去多久,那段在网吧通宵鏖战,跟同学朋友在副本、战场度过无数日子的青春一直烙印在心底深处,无法忘怀!
好了,废话不多说,开始进入正题
———————————————————————————————————————
大家都知道,php 作为一门脚本语言,对于没什么基础的人来说比较容易上手,但是很难精通,随着互联网的逐步兴起,php 也火热起来,在这种需求的催动下,大量人员涌入到 php 的开发中来,多年之后,一度让人认为 php 只能写写网站、脚本、接口,随后而来的就是语言鄙视链,写汇编语言的工程师都鄙视写 C 语言的工,写 C 语言的工程师都鄙视写 C ++ 的,C++ 工程师鄙视写 Java 的和写 C# 的,Java 工程师和 C# 工程师则相互鄙视,然而,所有的工程师都鄙视 PHP 工程师,于是这句著名的自嘲式的“php 是世界上最好的语言”在互联网圈子流传开来~~
SO, 假定“php 是世界上最好的语言”这句话为真,那我们用它来构建一个游戏服务端怎么样?
“真的吗?”
“可以吗”
“真的!”
“可以!”
小打小闹的什么页游啊、棋牌啊直接忽视,来个挑战高的,难度大的!那就魔兽世界吧!哈哈哈哈哈哈哈哈哈哈~
但是写游戏服务端我们要做些什么呢,我也不知道,我也不敢问啊,让别人知道你想用 php 写魔兽世界服务端,会招来各种花式嘲讽的!
于是偷偷的装了抓包工具,偷偷的研究起了魔兽世界游戏的逻辑,得出结论,
1 魔兽世界服务端需要一个用户登录 (authserver) 服务器用来处理用户登录鉴权,客户端与服务端使用 TCP 协议, 端口号为 3724
2 需要一个世界 (worldserver) 服务器来处理游戏逻辑,包含角色的创建,地图的加载,npc 和生物的构建及各种眼花缭乱的物品和技能等等~ 同样是 TCP 协议,这里的端口号为 8085
第一步:用 php 构建用户登录服务器 -AuthServer
我这里采用 Swoole 扩展 (不知道的自行百度) 创建了 TCP 服务监听了本机的 3724 端口
用户登录服务器主要的逻辑是:wow 客户端发送账户信息给服务端,服务端验证账户并告知客户端鉴权结果,结果中包含世界服务器的地址及端口。
偷偷说一句,魔兽的客户端在登录的时候只会发送一些基本信息,并不包含明文密码,而是使用 SRP 认证
SRP 简化后的原理是:
- 服务器不保存密码或密码的散列值,防止字典攻击,而只是保存验证因子(verifier)
- 客户端和服务器可以各自计算出一个会话秘钥(session key),其值相同 防止窃听
第二步 构建世界服务器 -WorldServer
与上面一样,需要绑定本机的 8085 端口
小提示: 3724 和 8085 的 TCP/UDP 已经被暴雪注册了…简单说,暴雪注册了专有的端口号用于专门的战网通信以及魔兽世界的通信。以前大家(数据包)都从一个门(端口)进进出出,现在暴雪大爷有钱了,弄了个专门的门,以后爷走这个门,你们都不许走。牛逼吧!
魔兽客户端在用户登录服务器鉴权成功后就会连接到世界服务器,首次接入服务端会向客户端发起鉴权数据包,其中带有服务器随机密钥,客户端收到之后根据密钥和 sessionkey 计算出 client_hash,并发送给服务端,服务端使用相同公式计算出 server_hash 判断是否一致
服务端鉴权完成后的所有数据包都将进行加密
先使用 hash_hmac 对 sessionkey 生成指定的哈希运算规则数据,
然后根据数据包的 Opcode 生成数据包头,然后发送结果给客户端
客户端收到鉴权成功结果后,会发送获取角色信息的数据包,服务端进行处理,获取角色信息并发送给客户端
客户端点击进入魔兽世界后,发送 CMSG_PLAYER_LOGIN 操作码。服务端接收并处理
还挺多的~ 就不一一详细写了
进入魔兽世界后就是这个样子
完整运行视频(Swoole 创始人韩天峰的微博): https://weibo.com/tv/v/I7Hu7dVxG?fid=1034:4418354417756012
到此一个简单的魔兽世界服务器就构建完了! 怎么样? 哈哈哈,php 是不是世界上最好的语言!
不过话说回来,我目前做到的也是一些很基础的东西,毕竟魔兽世界那么大,想要一一实现靠一个人或一门语言是不可能的,可以做和不能做完全是两个概念,使用 php 是比较方便,高效且便捷,但是性能我无法完全保证,不过使用 swoole 和 php7 之后,这点就不是我去考虑的了,够用,还可以!
代码我已经开源,地址是:https://github.com/fan3750060…
谢谢!来!让我们一起说:php 是世界上最好的语言!