热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用socks5将游戏的服务器连接通过本地SS服务器代理连接到加速服务器,实现游戏加速。

水平有限,简单记录下实现过程:首先准备一个开源项目SSCAPhttps:sourceforge.netpsscapcodecimastertree(c

水平有限,简单记录下实现过程:

首先准备一个开源项目SSCAP https://sourceforge.net/p/sscap/code/ci/master/tree/ (c++ mfc sscap源码)。

SSCap是一个本地代理服务器,SSCap是一个Windows下C++版的Shadowsocks客户端. 相比其它的客户端更稳定更快速,不会出现其它版本中常现的接收数据错误。

通过SSCap可以启动本地代理服务器。你可以让IE或其他需要软件通过SOCKS5访问的软件先连接到 SSCAP,SSCAP再将请求加密后再连接到服务器。服务器可以将请求转发到国外游戏服务器,实现网络游戏加速。

SSCAP界面:

SSCap是开源的。本文将SScap的功能整合起来。实现对魔兽世界怀旧服LH网络加速的功能。

原理很简单:

1、先整合sscap的功能,将本地服务器启动起来。

// 加载ss服务器列表CSSConfigInfo *pCfg = GetConfigInfo();CSSNodeInfo* pNode = new CSSNodeInfo(0);pNode->id = 0;pNode->server = "140.0.0.00";pNode->server_port = 65501;pNode->password = "1234"; pNode->method = "aes-256-cfb";pNode->enable = true;pNode->Upload_traffic = 7450.00;pNode->Download_traffic = 21477.00;pNode->ConnectedTimes = 12;pNode->lastStatus = -1;pCfg->ssNodeInfo.clear();pCfg->ssNodeInfo.push_back(pNode);pCfg->localSocksUser = "local_user";pCfg->localSocksPass = "local_pass";pCfg->localPort = 1080;pCfg->isPrivoxyRunned = RunPrivoxy( );RestartLocalSocketService(FALSE);

那么本地服务器就启动好了。127.0.0.1:1080  登陆账号:local_user    登陆密码:local_pass

2、启动魔兽世界6.0。注入DLL,拦截ws2_32.dll的connect方法。

DetourRestoreAfterWith();//恢复原来的状态DetourTransactionBegin();//拦截开始DetourUpdateThread(GetCurrentThread());//刷新当前线程 //以下为hook connect内容g_trueConnect = (_gconnect)DetourFindFunction("Ws2_32.dll", "connect");g_trueWSAConnect = (_gWSAConnect)DetourFindFunction("Ws2_32.dll", "WSAConnect");DetourAttach(&(PVOID&)g_trueConnect,hook_connect);DetourAttach(&(PVOID&)g_trueWSAConnect,hook_WSAConnect);if( DetourTransactionCommit() == NO_ERROR )//拦截生效{WriteLog(_T("hook success"));}elseWriteLog(_T("hook faild"));

int _stdcall hook_connect(SOCKET s, struct sockaddr *name, int namelen)
{CString strDbgInfo;strDbgInfo.Format(_T("Socket in hook connect:%d"),s);//修改目的IP为VIPSOCKADDR_IN* addr =(SOCKADDR_IN*)name;//如果IP是指定要修改端口的IP,就改掉端口char * ipaddr=NULL;ipaddr = inet_ntoa(addr->sin_addr);//原游戏连接信息TCHAR temp[255];memset(temp,0,255); char* proxyserver = "127.0.0.1";int proxyport = 1081;char* proxyuser = "local_user";char* proxypwd = "local_pass";int iRet = ConnecToProxyServer(s,proxyserver,proxyport,proxyuser,proxypwd,3,ipaddr,ntohs(addr->sin_port));if (iRet>=0){WriteLog(_T("in connecta: connect socks5 success 1!"));}else{memset(temp,0,255);wsprintf(temp,_T("Err connect ss5:%d"),iRet);WriteLog(temp);}return iRet;
}

//代理服务器登录
//char* g_proxyserver = "140.1xx.1x.1xx";
//int g_proxyport = 65500;
//char* g_proxyuser = "";
//char* g_proxypwd = "";
//int g_proxyid = 3; //2 - sock4代理 3 - sock5代理
//char server_name[100]= {0}; //真正的服务器地址
//int server_port=8000; //真正的服务器端口
int ConnecToProxyServer(SOCKET m_hSocketpop,char* g_proxyserver,int g_proxyport,char* g_proxyuser,char* g_proxypwd,int g_proxyid,char* server_name,int server_port,int connectType)
{//原游戏连接信息SOCKADDR_IN ToAddr;memset(&ToAddr, 0, sizeof(ToAddr));ToAddr.sin_family &#61; AF_INET; ToAddr.sin_addr.s_addr &#61; inet_addr(g_proxyserver);//这是我的SOCKS服务器ToAddr.sin_port &#61; htons(g_proxyport); int retCt &#61; -1;if (connectType &#61;&#61; 1)retCt &#61; g_trueWSAConnect(m_hSocketpop,(SOCKADDR*)&ToAddr,sizeof(ToAddr),NULL,NULL,NULL ,NULL);elseretCt &#61; g_trueConnect(m_hSocketpop,(SOCKADDR*)&ToAddr,sizeof(ToAddr));if( SOCKET_ERROR &#61;&#61; retCt ){int iErr &#61; WSAGetLastError(); if (iErr&#61;&#61;WSAEWOULDBLOCK){fd_set fdWrite;timeval tv;FD_ZERO(&fdWrite);//初始化fd_setFD_SET(m_hSocketpop,&fdWrite);tv.tv_sec &#61; 30;tv.tv_usec &#61; 0;int nRet &#61; select(0,NULL,&fdWrite,NULL,&tv);if (nRet<&#61;0){closesocket(m_hSocketpop);return -111;}}else{closesocket(m_hSocketpop);return -112;}}char buf[100] &#61; {0};if(g_proxyid &#61;&#61; 3) //sock5 代理方式{// 让PROXY选择认证方法buf[0] &#61; 0x05;buf[1] &#61; 0x02; //确认2种认证方式 无需认证和需要认证buf[2] &#61; 0x00; // 无需认证buf[3] &#61; 0x02; // 需要认证WriteLog(_T("Send a request asking if authentication is required"));if(send(m_hSocketpop,(const far char*)buf,4,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -12;}//查询是否有返回fd_set fdread;timeval tv;FD_ZERO(&fdread);//初始化fd_setFD_SET(m_hSocketpop,&fdread);tv.tv_sec &#61; 30;tv.tv_usec &#61; 0;int nRet;nRet &#61; select(0,&fdread,NULL,NULL,&tv);if (nRet<&#61;0){return -122;}//接收返回if(recv(m_hSocketpop,buf,10,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -13;}if(buf[1] &#61;&#61; 0x02){//需要认证WriteLog(_T("need auth"));char userStr[128] &#61; {0};userStr[0]&#61;0x01;userStr[1]&#61;strlen(g_proxyuser);strcpy(userStr&#43;2,g_proxyuser);userStr[2&#43; strlen(g_proxyuser)]&#61; strlen(g_proxypwd);strcpy(userStr&#43;3&#43; strlen(g_proxyuser),g_proxypwd);int result&#61;send(m_hSocketpop,userStr,strlen(userStr), 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}Sleep(100);char validateChar[2] &#61; {1};result&#61;recv(m_hSocketpop,validateChar,2, 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}if(validateChar[1]!&#61;&#39;\x00&#39;){//认证失败closesocket(m_hSocketpop);return -1;}}// 向PROXY服务器发送CONNECT 请求&#xff0c;WriteLog(_T("Send connect request to PROXY server!"));memset(buf, 0, 100);buf[0] &#61; 0x05;buf[1] &#61; 0x01; // connection request.buf[2] &#61; 0x00; // reserved!buf[3] &#61; 0x01; // address type:Ip V4 ;*((ULONG*)(buf&#43;4))&#61;inet_addr(server_name);*((USHORT*)(buf&#43;8))&#61;htons(server_port);if(send(m_hSocketpop,(const far char*)buf,10,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -14;}//Sleep(100); FD_ZERO(&fdread);//初始化fd_setFD_SET(m_hSocketpop,&fdread);tv.tv_sec &#61; 30;tv.tv_usec &#61; 0;nRet &#61; select(0,&fdread,NULL,NULL,&tv);if (nRet<&#61;0){return -141;}// 接收PROXY服务器返回的REPLYmemset(buf, 1, 100);if(recv(m_hSocketpop,buf, 20,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -15;}if(buf[1] !&#61; 0) // 只有当第二个字节为0时&#xff0c;才表示成功。{// printf("Cannot connect to the remote server!\n");closesocket(m_hSocketpop);return -16;}// theApp.m_ClientSocket.Attach(m_hSocketpop);}if(g_proxyid &#61;&#61; 2) //sock4 代理方式{int result;memset(buf, 0, 100);buf[0] &#61; 0x04;buf[1] &#61; 0x01; // connection request.*((USHORT*)(buf&#43;2))&#61;htons(server_port);*((ULONG*)(buf&#43;4))&#61;inet_addr(server_name);buf[8] &#61; 0x00;result &#61; send(m_hSocketpop, (const far char*)buf, 9, 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}Sleep(100);char EchoStr[10];memset(EchoStr,0,10);result&#61;recv(m_hSocketpop,EchoStr,8, 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}if(EchoStr[1] !&#61; 90){closesocket(m_hSocketpop);return -1;}// theApp.m_ClientSocket.Attach(m_hSocketpop);}return 0;
}

游戏会建立与本地服务器的连接&#xff0c;本地服务器会将游戏请求通过sock5发送到服务器上。实现游戏加速。

服务端架设参考&#xff1a;

用shadowsocks-libev架设服务器端&#xff1a;

https://blog.csdn.net/wwzuizz/article/details/78194159


推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
author-avatar
张群羽圣文
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有