距离魔兽世界乌龟服亚服已经开了已经半年多了,对我一个偶尔想玩下的人是非常合适的,原汁原味,而且还免费。但是它有一点很恶心就是既然服务器在香港了,为什么不来点国内优化,还得用加速器。作为VPSer我就想能否用现有的资源给游戏加速下,最好啥软件都不用的前提下就能加速(毕竟加速器是只能1个人登录不能共享)。
前言 魔兽世界乌龟服亚服 (Turtle WOW 艾泽拉斯的秘密 - 亚洲领域) 是欧洲非常出名的魔兽世界私服,在去年9月上线了亚洲服务器(差不多就是为国人准备的)它开发团队甚至改写地图,改写游戏任务,以及多种特色玩法来增加游戏体验。以至于原本你打一个怪都是生不如死的,到现在在不影响体验的前提下,因为任务增多所以等级会比升更快,几乎每一次从越级打怪变成了降级打怪,哪怕是战士也是很好的一个人玩,而且它对工作室,金团打击非常严格,游戏体验好得多。但是它有一个很恶心的地方,就是从内地直连延迟很高,因为我有一台深港的服务器,从深圳到香港几乎5ms的延迟,我就在想能否用这台服务器来为游戏加个速。
这里不会涉及任何与代理相关的国内非法软件
折腾原因 玩过魔兽世界私服的都知道,魔兽世界1.12游戏目录下,有一个realmlist.wtf
的文件,这个文件决定了当前游戏客户端连接着哪一个服务端,这个文件内容是这样的 当然下面的地址早就不能用了,这是九城的魔兽世界服务器地址
1 set realmlist cn1.logon.warcraftchina.com
乌龟服 Turtle WOW 的realmlist.wtf是这样的,我们用 BestTrace 来看下路由
1 2 set realmlist cnlogon.turtle-wow.org set patchlist cnlogon.turtle-wow.org
路由路线
从上面的图,我们可以看到,它访问游戏登陆服务器,会先跑到美国,然后从美国访问香港,这延迟不高才怪。就像我们去香港,先要坐飞机到美国,然后再美国飞往香港,这时间没个一天一夜都困难。至于为什么会出现这个情况,很简单一句话:服务器商家给国内运营商的钱不够多。 加速器的原理就很简单,说到底加速器就是让你坐上直达班车,使得你能快速到香港。
传统加速原理 这是我们此刻访问游戏服务器
而这是使用网易UU加速器访问游戏服务器
基本加速原理都是如此,使用更优化的网络来为游戏加速。所以,我就在想,魔兽世界既然提供了设置服务器地址,那么游戏服务器肯定也是在这里面。
开始折腾 丢个想法 我们都知道魔兽世界登陆账号后,会有一个选择服务器的过程,每一个服务器应该是一个独立的端口或IP,然后每一个私服都有自己的服务器名字,所以这里我猜测,游戏服务器的IP和端口信息,很有可能是由登陆服务器提供的,但是是否是加密信息就不清楚了。只不过有如此多的私服,加密方式应该也不是啥秘密 其实,它压根没有加密
抓包 基于上述的结论,我用wiresharek进行抓包,我打开抓包后,并进行登陆,选择服务器,登陆到角色,得到的数据包如下,好吧,wiresharek都已经能识别到wow游戏包了。
我们找到最后一条,Realm List
数据大小是281的数据包,内容如下
这不是就是我要找的数据么,数据命令是 Realm List 0x10,数据包大小224,共5个领域,这就是我需要的。
然后我找第一个服务器 Blood Ring,看看里面的值,它的服务器地址就是 169.150.222.245:8090
思路明确 因为我有一台 深圳到香港几乎5ms的延迟的服务器,所以我是不是可以这么做
我首先写一个代理服务器,代理它的认证端口3724(从抓包软件得知,魔兽世界端口是3724)
修改服务器地址,让游戏能连接到我深圳服务器
然后我将所有15001端口的请求全部转发到原来的服务器
登陆成功,游戏ing
这样子,我就不需要在电脑上装任何软件,只需要代理服务部署在服务端,只需修改配置,就可以不需要加速器,不需要任何软件的前提下,玩上低延迟的游戏了。
p.s. 如果你有一台香港对国内优化服务器,那么也可以作为加速游戏使用
开始编码 实现登陆部分 首先我需要能转发代理登陆部分,实现捕获魔兽世界登陆服务器,我使用java socket来实现请求。代码如下,这段代码能帮我们实现转发登录请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 package com.ruterfu;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class SocketForwarder { private static final String LOGIN_SERVER = "169.150.222.73" ; private static final int LOGON_PORT = 3724 ; private static final int SOCKET_LISTEN = 16000 ; private static final String logonServer = LOGIN_SERVER; public static void main (String[] args) { try { ServerSocket serverSocket = new ServerSocket (SOCKET_LISTEN); System.out.println("Listening on port " + SOCKET_LISTEN + "..." ); while (true ) { Socket clientSocket = serverSocket.accept(); clientSocket.setSoTimeout(60000 ); System.out.println("Connection from " + clientSocket.getInetAddress()); Thread clientThread = new Thread (new ClientHandler (clientSocket, true )); clientThread.start(); } } catch (IOException e) { e.printStackTrace(); } } private record ClientHandler (Socket clientSocket, boolean needReplace) implements Runnable { @Override public void run () { try (Socket serverSocket = new Socket (logonServer, LOGON_PORT); InputStream clientInput = clientSocket.getInputStream(); OutputStream clientOutput = clientSocket.getOutputStream(); InputStream serverInput = serverSocket.getInputStream(); OutputStream serverOutput = serverSocket.getOutputStream()) { byte [] buffer = new byte [4096 ]; int bytesRead; while ((bytesRead = clientInput.read(buffer)) != -1 ) { serverOutput.write(buffer, 0 , bytesRead); serverOutput.flush(); System.out.println("sent " + bytesRead + " data to server" ); bytesRead = serverInput.read(buffer); System.out.println("received(first buffer 【" + buffer[0 ] + "】) " + new String (buffer, 0 , bytesRead) + " data from server" ); clientOutput.write(buffer, 0 , bytesRead); clientOutput.flush(); } System.out.println("Connection from " + clientSocket.getInetAddress() + " closed" ); } catch (IOException e) { e.printStackTrace(); } } } }
运行这段代码,将游戏服务器地址改成自己本机地址(我这里是虚拟机运行 + 本地跑java),输出日志如下,看到需要的数据了,此时游戏也进入了角色选择画面,表示已经成功收到原始的文本了然后这里要做的就是,将原始文本进行修改,然后将其返回给游戏客户端就行了
1 2 3 4 5 6 7 8 9 10 Connection from /10.211.55.5 reading data from client sent 41 data to server received(first buffer 【0】) =��K+�O_˦����̌萳ۯZDϚYI�m�; ��>*��<��^����SP)�[��[S�^dK��q/�)@���M������֓��b����OU�����!W�7?�i��� data from server reading data from client sent 75 data to server received(first buffer 【1】) ���cM8� �DŽ�n�lD� data from server reading data from client sent 5 data to server received(first buffer 【16】) � Blood Ring 169.150.222.245:8090 E� ? Emerald Dream 169.150.222.71:8090 ��? Hogger 169.150.222.69:8090 ��R? Ravenshire 169.150.222.223:8090 Z+? Stormstout 169.150.222.244:8090 �'�>