📄 rundb.~pas
字号:
unit RunDB;
interface
uses
Windows,SysUtils,Grobal2,SDK,M2Share,WinSock;
procedure DBSocketThread(ThreadInfo:pTThreadInfo);stdcall;
function DBSocketConnected():Boolean;
function GetDBSockMsg(nQueryID:Integer;var nIdent:integer;var nRecog:integer;var sStr:String;dwTimeOut:LongWord;boLoadRcd:Boolean):Boolean;
function MakeHumRcdFromLocal(var HumanRcd:THumDataInfo):Boolean;
function LoadHumRcdFromDB(sAccount,sCharName,sStr:String;var HumanRcd:THumDataInfo;nCertCode:Integer):Boolean;
function SaveHumRcdToDB(sAccount,sCharName:String;nSessionID:Integer;var HumanRcd:THumDataInfo):Boolean;
function SaveRcd(sAccount,sCharName:String;nSessionID:Integer;var HumanRcd:THumDataInfo):Boolean; //004B42C8
function NewYsRcd(sAccount,sChrName:string;bHair,bJob,bSex:byte;sYsnameMaster:String;nSessionID:Integer):Boolean;
function DBLocalIp():Boolean;
function LoadRcd(sAccount,sCharName,sStr:String;nCertCode:Integer;var HumanRcd:THumDataInfo):Boolean;
procedure SendDBSockMsg(nQueryID:Integer;sMsg:String);
function GetQueryID(Config:pTConfig):Integer;
implementation
uses svMain, HUtil32, EDcode;
function GetCodeMsgSize(X: Double):Integer;
begin
if INT(X) < X then Result:=TRUNC(X) + 1
else Result:=TRUNC(X)
end;
procedure DBSocketRead(Config:pTConfig);
var
dwReceiveTimeTick:LongWord;
nReceiveTime:Integer;
sRecvText:String;
nRecvLen:Integer;
nRet:Integer;
begin
if Config.DBSocket = INVALID_SOCKET then exit;
dwReceiveTimeTick:=GetTickCount();
nRet:=ioctlsocket(Config.DBSocket, FIONREAD, nRecvLen);
if (nRet = SOCKET_ERROR) or (nRecvLen = 0) then begin
nRet:=WSAGetLastError;
Config.DBSocket:=INVALID_SOCKET;
Sleep(100);
Config.boDBSocketConnected:=False;
exit;
end;
SetLength(sRecvText,nRecvLen);
nRecvLen:=recv(Config.DBSocket,Pointer(sRecvText)^,nRecvLen,0);
SetLength(sRecvText, nRecvLen);
Inc(Config.nDBSocketRecvIncLen,nRecvLen);
if (nRecvLen <> SOCKET_ERROR) and (nRecvLen > 0) then begin
if nRecvLen > Config.nDBSocketRecvMaxLen then Config.nDBSocketRecvMaxLen:=nRecvLen;
EnterCriticalSection(UserDBSection);
try
Config.sDBSocketRecvText:=Config.sDBSocketRecvText + sRecvText;
if not Config.boDBSocketWorking then begin
Config.sDBSocketRecvText:='';
end;
finally
LeaveCriticalSection(UserDBSection);
end;
end;
Inc(Config.nDBSocketRecvCount);
nReceiveTime:=GetTickCount - dwReceiveTimeTick;
if Config.nDBReceiveMaxTime < nReceiveTime then Config.nDBReceiveMaxTime:=nReceiveTime;
end;
procedure DBSocketProcess(Config:pTConfig;ThreadInfo:pTThreadInfo);
var
s :TSocket;
name :sockaddr_in;
HostEnt :PHostEnt;
argp :LongInt;
readfds :TFDSet;
timeout :TTimeVal;
nRet :Integer;
boRecvData :BOOL;
nRunTime :Integer;
dwRunTick :LongWord;
begin
s:=INVALID_SOCKET;
if Config.DBSocket <> INVALID_SOCKET then
s:= Config.DBSocket;
dwRunTick:=GetTickCount();
ThreadInfo.dwRunTick:=dwRunTick;
boRecvData:=False;
while True do begin
if ThreadInfo.boTerminaled then break;
if not boRecvData then Sleep(1)
else Sleep(0);
boRecvData:=False;
nRunTime:=GetTickCount - ThreadInfo.dwRunTick;
if ThreadInfo.nRunTime < nRunTime then ThreadInfo.nRunTime:=nRunTime;
if ThreadInfo.nMaxRunTime < nRunTime then ThreadInfo.nMaxRunTime:=nRunTime;
if GetTickCount - dwRunTick >= 1000 then begin
dwRunTick:=GetTickCount();
if ThreadInfo.nRunTime > 0 then Dec(ThreadInfo.nRunTime);
end;
ThreadInfo.dwRunTick:=GetTickCount();
ThreadInfo.boActived:=True;
ThreadInfo.nRunFlag:=125;
if (Config.DBSocket = INVALID_SOCKET) or (s = INVALID_SOCKET) then begin
if Config.DBSocket <> INVALID_SOCKET then begin
Config.DBSocket := INVALID_SOCKET;
Sleep(100);
ThreadInfo.nRunFlag:=126;
Config.boDBSocketConnected:=False;
end;
if s <> INVALID_SOCKET then begin
closesocket(s);
s:=INVALID_SOCKET;
end;
if Config.sDBAddr = '' then Continue;
s:=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if s = INVALID_SOCKET then Continue;
ThreadInfo.nRunFlag:=127;
HostEnt:=gethostbyname(PChar(@Config.sDBAddr[1]));
if HostEnt = nil then Continue;
PInteger(@name.sin_addr.S_addr)^:=PInteger(HostEnt.h_addr^)^;
name.sin_family:=HostEnt.h_addrtype;
name.sin_port:=htons(Config.nDBPort);
name.sin_family:=PF_INET;
ThreadInfo.nRunFlag:=128;
if connect(s,name,SizeOf(name)) = SOCKET_ERROR then begin
nRet:=WSAGetLastError;
closesocket(s);
s:=INVALID_SOCKET;
Continue;
end;
argp:=1;
if ioctlsocket(s,FIONBIO,argp) = SOCKET_ERROR then begin
closesocket(s);
s:=INVALID_SOCKET;
Continue;
end;
ThreadInfo.nRunFlag:=129;
Config.DBSocket:=s;
Config.boDBSocketConnected:=True;
end;
readfds.fd_count:=1;
readfds.fd_array[0]:=s;
timeout.tv_sec:=0;
timeout.tv_usec:=20;
ThreadInfo.nRunFlag:=130;
nRet:=select(0,@readfds,nil,nil,@timeout);
if nRet = SOCKET_ERROR then begin
ThreadInfo.nRunFlag:=131;
nRet:=WSAGetLastError;
if nRet = WSAEWOULDBLOCK then begin
Sleep(10);
Continue;
end;
ThreadInfo.nRunFlag:=132;
nRet:=WSAGetLastError;
Config.nDBSocketWSAErrCode:=nRet - WSABASEERR;
Inc(Config.nDBSocketErrorCount);
Config.DBSocket:=INVALID_SOCKET;
Sleep(100);
Config.boDBSocketConnected:=False;
closesocket(s);
s:=INVALID_SOCKET;
Continue;
end;
boRecvData:=True;
ThreadInfo.nRunFlag:=133;
while True do begin
if nRet <= 0 then break;
DBSocketRead(Config);
Dec(nRet);
end;
end;
if Config.DBSocket <> INVALID_SOCKET then begin
Config.DBSocket:=INVALID_SOCKET;
Config.boDBSocketConnected:=False;
end;
if s <> INVALID_SOCKET then begin
closesocket(s);
end;
end;
procedure DBSocketThread(ThreadInfo:pTThreadInfo);stdcall;
var
nErrorCount:Integer;
ResourceString
sExceptionMsg = '[Exception] DBSocketThread ErrorCount = %d';
begin
nErrorCount:=0;
while True do begin
try
DBSocketProcess(ThreadInfo.Config,ThreadInfo);
break;
except
Inc(nErrorCount);
if nErrorCount > 10 then break;
MainOutMessage(format(sExceptionMsg,[nErrorCount]));
end;
end;
ExitThread(0);
end;
function DBSocketConnected():Boolean;
begin
{$IF DBSOCKETMODE = TIMERENGINE}
Result:=FrmMain.DBSocket.Socket.Connected;
{$ELSE}
Result:=g_Config.boDBSocketConnected;
{$IFEND}
end;
function GetDBSockMsg(nQueryID:Integer;var nIdent:integer;var nRecog:integer;var sStr:String;dwTimeOut:LongWord;boLoadRcd:Boolean):Boolean;
var
boLoadDBOK:Boolean;
dwTimeOutTick:LongWord;
s24,s28,s2C,sCheckFlag,sDefMsg,s38:String;
nLen:Integer;
nCheckCode:Integer;
DefMsg:TDefaultMessage;
ResourceString
sLoadDBTimeOut = '[RunDB] 读取人物数据超时...';
sSaveDBTimeOut = '[RunDB] 保存人物数据超时...';
begin
boLoadDBOK:=False;
Result:=False;
dwTimeOutTick:=GetTickCount();
While(True) do begin
if (GetTickCount - dwTimeOutTick) > dwTimeOut then begin
n4EBB6C:=n4EBB68;
break;
end;
s24:='';
EnterCriticalSection(UserDBSection);
try
if Pos('!',g_Config.sDBSocketRecvText) > 0 then begin
s24:=g_Config.sDBSocketRecvText;
g_Config.sDBSocketRecvText:='';
end;
finally
LeaveCriticalSection(UserDBSection);
end;
if s24 <> '' then begin
s28:='';
s24:=ArrestStringEx(s24,'#','!',s28);
if s28 <> '' then begin
s28:=GetValidStr3(s28, s2C, ['/']);
nLen:=Length(s28);
if (nLen >= SizeOf(TDefaultMessage)) and (Str_ToInt(s2C,0) = nQueryID) then begin
nCheckCode:=MakeLong(Str_ToInt(s2C,0) xor 170,nLen);
sCheckFlag:=EncodeBuffer(@nCheckCode,SizeOf(Integer));
if CompareBackLStr(s28,sCheckFlag,Length(sCheckFlag)) then begin
if nLen = DEFBLOCKSIZE then begin
sDefMsg:=s28;
s38:=''; // -> 004B3F56
end else begin//004B3F1F
sDefMsg:=Copy(s28,1,DEFBLOCKSIZE);
s38:=Copy(s28,DEFBLOCKSIZE + 1,Length(s28) - DEFBLOCKSIZE -6);
end;//004B3F56
DefMsg:=DecodeMessage(sDefMsg);
nIdent:=DefMsg.Ident;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -