易语言linux登录器网关源码,Mir2源码详解之服务端-登录网关(LoginGate)

阅读: 评论:0

易语⾔linux登录器⽹关源码,Mir2源码详解之服务端-登录⽹关
(LoginGate)
传奇这款游戏,⼀直对我的影响很⼤。当年为了玩传奇,逃课,被⽼师叫过N次家长。⾔归正传,⽹上有很多源码,当然了,都是delphi 的。并且很多源码还不全,
由于⼀直学习的c、c++。delphi还真不懂。⽆奈硬着头⽪上。好了。废话不多说。开始。
登录⽹关,负责游戏最开始的登录处理(与账户服务器LoginSvr通讯)。验证登录器输⼊的账户密码是否正确。
界⾯上的控件很多。其实⼲活的就 就 三个:“TServerSocket”、“TClientSocket”、“DecodeTimer”这三个控件。
ServerSocket:负责与登录器进⾏通讯,它做的操作:
1、接收连接,代码如下:
{
函数功能:接受客户端连接,发送消息到 登录服务器
}
procedure TFrmMain.ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
UserSession:pTUserSession;
sRemoteIPaddr,sLocalIPaddr:String;
nSockIndex:Integer;
IPaddr :pTSockaddr;
begin
Socket.nIndex:=-1;
// 客户端IP地址
sRemoteIPaddr:=Socket.RemoteAddress;
if g_boDynamicIPDisMode then begin
sLocalIPaddr:=ClientSocket.Socket.RemoteAddress;
end else begin
sLocalIPaddr:=Socket.LocalAddress;
end;
// 过滤ip
if IsBlockIP(sRemoteIPaddr) then begin MainOutMessage('过滤连接: ' + sRemoteIPaddr,1); Socket.Close;
exit;
end;
// 当前IP是否可以连接
if IsConnLimited(sRemoteIPaddr) then begin
case BlockMethod of
// 断开
mDisconnect: begin
Socket.Close;
end;
// 动态过滤
mBlock: begin
New(IPaddr);
IPaddr.nIPaddr:=inet_addr(PChar(sRemoteIPaddr)); TempBlockIPList.Add(IPaddr);
CloseConnect(sRemoteIPaddr);
end;
// 永久过滤
mBlockList: begin
New(IPaddr);
IPaddr.nIPaddr:=inet_addr(PChar(sRemoteIPaddr)); BlockIPList.Add(IPaddr);
CloseConnect(sRemoteIPaddr);
end;
end;
MainOutMessage('端⼝攻击: ' + sRemoteIPaddr,1); exit;
end;
// 如果⽹关准备好了
if boGateReady then begin
for nSockIndex:= 0 to GATEMAXSESSION - 1 do begin UserSession:=@g_SessionArray[nSockIndex];
if UserSession.Socket = nil then begin UserSession.Socket:=Socket;
UserSession.sRemoteIPaddr:=sRemoteIPaddr; UserSession.nSendMsgLen:=0;
UserSession.bo0C:=False;
UserSession.dw10Tick:=GetTickCount(); UserSession.dwConnctCheckTick:=GetTickCount(); UserSession.boSendAvailable:=True; UserSession.boSendCheck:=False;
UserSession.nCheckSendLength:=0; UserSession.n20:=0;
UserSession.dwUserTimeOutTick:=GetTickCount(); UserSession.SocketHandle:=Socket.SocketHandle; UserSession.sIP:=sRemoteIPaddr;
UserSession.MsgList.Clear;
Socket.nIndex:=nSockIndex;
Inc(nSessionCount);
break;
end;
end;
// 和本地登录服务器进⾏通讯
if Socket.nIndex >= 0 then begin
ClientSocket.Socket.SendText('%O' +
IntToStr(Socket.SocketHandle) +
'/' +
sRemoteIPaddr +
'/' +
自动削皮机
sLocalIPaddr +雾化吸入器
'$');
MainOutMessage('Connect: ' + sRemoteIPaddr,5); end else begin
Socket.Close;
MainOutMessage('Kick Off: ' + sRemoteIPaddr,1); end;
end else begin //0x004529EF
Socket.Close;
MainOutMessage('Kick Off: ' + sRemoteIPaddr,1);
end;
电子煎药壶end;
说⽩了,别看 那些IP过滤规则和连接限制什么的。就是 来了⼀⽤户,直接保存到⼀个 UserSession中。然后通知LoginSvr,有⼈连接了。。现在市⾯上的什么:GOM引擎、Hero、HGE(原3K、IGE)、Legend、GEEM2、77M2都是换汤不换药。变的就是 加密⽅式。这⾥不得不说,JsocketJ就是TServerSocket、TClientSocket的控件,懒得看源码,看了下其属性,⼤致就可以了解到。
是采⽤的线程池的select模型。早期的游戏,都采⽤这种⽅式,不过,对于私*服,连接量不⼤,完全⾜够应付。其实有更好的解决办法,那就是IOCP来管理。效率更⾼。windows下最适合的模型了。
2、断开连接,代码如下:
procedure TFrmMain.ServerSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
一氧化氮合成酶
I:Integer;
UserSession:pTUserSession;
nSockIndex:Integer;
sRemoteIPaddr:String;
IPaddr :pTSockaddr;
nIPaddr :Integer;
begin
sRemoteIPaddr:=Socket.RemoteAddress;
蛋白层析系统nIPaddr:=inet_addr(PChar(sRemoteIPaddr));
nSockIndex:=Socket.nIndex;
for I := 0 to CurrIPaddrList.Count - 1 do begin
IPaddr:=CurrIPaddrList.Items[I];
三自由度摇摆台
if IPaddr.nIPaddr = nIPaddr then begin
Dec(IPaddr.nCount);
if IPaddr.nCount <= 0 then begin
Dispose(IPaddr);
CurrIPaddrList.Delete(I);
end;
Break;
end;
end;
if (nSockIndex >= 0) and (nSockIndex < GATEMAXSESSION) then begin UserSession:=@g_SessionArray[nSockIndex];
UserSession.Socket:=nil;
UserSession.sRemoteIPaddr:='';
UserSession.SocketHandle:=-1;
UserSession.MsgList.Clear;
Dec(nSessionCount);
if boGateReady then begin
ClientSocket.Socket.SendText('%X' +
IntToStr(Socket.SocketHandle) +
'$');
MainOutMessage('DisConnect: ' + sRemoteIPaddr,5);
end;
end;
end;
删除,释放,并通知 LoginSvr,有⼈断开连接了。。。
3、接收数据,代码如下:
procedure TFrmMain.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
UserSession:pTUserSession;
nSockIndex:Integer;
sReviceMsg,s10,s1C:String;
nPos:Integer;
nMsgLen:Integer;
begin
nSockIndex:=Socket.nIndex;
if (nSockIndex >= 0) and (nSockIndex < GATEMAXSESSION) then begin UserSession:=@g_SessionArray[nSockIndex];
sReviceMsg:=Socket.ReceiveText;
if (sReviceMsg <> '') and (boServerReady) then begin
nPos:=Pos('*',sReviceMsg);
if nPos > 0 then begin
UserSession.boSendAvailable:=True;

本文发布于:2023-05-19 11:39:43,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/2/105208.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:连接   登录   源码   客户端   游戏   释放   开始   过滤
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图