GOM引擎登录器的研究,逆向技术在这款GOM20151108引擎上是一个大舞台

news/2024/3/19 10:05:52/文章来源:https://blog.csdn.net/i735740559/article/details/127251754

        最近遇到一个逆向类课题,是关于GOM20151108版本对应登录器研究。刚接触传奇的时候是2002年,那时候网吧玩SF,都是手动用IP直接连接,当时的一款 联创传奇 很好玩,有传送戒子,木域戒指,土域戒指,麻痹戒子,护手戒子,法师的圣言术可以直接把2000厚血的教主直接秒掉,星星战甲这个衣服更是拉风,穿上直接是一个双头精钢。

         现在市场上主流微端模式的技术架构,到处都易语言写的登录器生成器,各种各样的版本。不过对于其中的技术,大部分都是一样的,只是有的插入了自己写的DLL。Delphi程式内存数据结构也比较特殊,这款GOM引擎客户端其实很小,只有3.5M左右。在注册账号、修改密码的功能上目前已经实现,接下来是是做客户端文件的启动,即 Clent.dat这个文件的启动,这个文件很多人被忽视,其实这个文件才是GOM引擎的核心精髓,所谓的引擎也主要是指这个文件,这个文件里面包含了游戏的所有逻辑代码。但是要调用起这个文件可没有那么容易,难点也是在这里。这个文件很多商业登录器生成器上直接隐藏的,被嵌入了登录器里面,dat文件其实也是和EXE结构一样的PE文件,即他们的做法是易语言写的EXE登录器和Delphi写的GOM20151108版本的Client.dat文件合并在一起,玩家点击登录器的时候就显示出登录器,玩家点击登录器界面上的启动游戏按钮后登录器是会创建一个和登录器本身一样的进程,不过这个进程启动界面是游戏画面的客户端程序,即Client.dat在内存中被创建,里面用到了PELoad的技术(也可以说是傀儡进程技术、僵尸进程技术,只是这次这种技术没有将系统进程作为宿主而已,而是将登录器作为了宿主启动了Client.dat)。此刻我们看到任务管理器上有两个登录器进程,其中一个其实不是登录器而是 Client.dat。小小一个登录器原来这么复杂,真是够隐蔽的,技术上其实已经超越了官方的登录器了。

         对于GOM的背景历史暂时不知道,只知道这款引擎非常的出色。但是在2015年11月8日被停止了更新,GOM官方解散了。网上有早期版本的源代码,都是delphi语言写的。但是网上应该没有人拿到2015年11月8日停更版本的源代码。只能靠逆向技术来给这款引擎加上额外的功能和优化了。

    

unit Main;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, jpeg, ExtCtrls, RzBmpBtn, StdCtrls, RzLstBox, RzButton, RzRadChk,OleCtrls, SHDocVw, ComCtrls, ShlObj, ComObj, ActiveX, Grobal2, JSocket,Registry, winsock, WinInet, ShellApi, IniFiles, GameShare, IdBaseComponent,IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, {ZLib,} tlHelp32, RzForms;typeTSearchThread = class(TThread)protectedprocedure Execute; override;publicconstructor Create(CreateSuspended: Boolean);destructor Destroy; override;end;TfrmMain = class(TForm)RzBmpButtonHomePage: TRzBmpButton;RzBmpButtonEditGameList: TRzBmpButton;RzBmpButtonNewAccount: TRzBmpButton;RzBmpButtonGetBakPassWord: TRzBmpButton;RzBmpButtonChgPassWord: TRzBmpButton;RzBmpButtonAutoLogin: TRzBmpButton;RzBmpButtonFullScreenStart: TRzBmpButton;RzBmpButtonClose: TRzBmpButton;Timer: TTimer;ClientSocket: TClientSocket;TimerStart: TTimer;CloseTimer: TTimer;RzBmpButtonMin: TRzBmpButton;TreeView: TTreeView;RzBmpButtonStart: TRzBmpButton;RzBmpButtonExitGame: TRzBmpButton;RzBmpButtonUpgrade: TRzBmpButton;Image: TRzFormShape;LabelStatus: TLabel;TimerReakSkin: TTimer;ComboBox: TComboBox;procedure TimerTimer(Sender: TObject);procedure ClientSocketConnect(Sender: TObject;Socket: TCustomWinSocket);procedure ClientSocketConnecting(Sender: TObject;Socket: TCustomWinSocket);procedure ClientSocketDisconnect(Sender: TObject;Socket: TCustomWinSocket);procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket;ErrorEvent: TErrorEvent; var ErrorCode: Integer);procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);procedure FormCreate(Sender: TObject);procedure RzBmpButtonCloseClick(Sender: TObject);procedure RzBmpButtonHomePageClick(Sender: TObject);procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);procedure RzBmpButtonFullScreenStartClick(Sender: TObject);procedure RzBmpButtonEditGameListClick(Sender: TObject);procedure TimerStartTimer(Sender: TObject);procedure RzBmpButtonNewAccountClick(Sender: TObject);procedure RzBmpButtonGetBakPassWordClick(Sender: TObject);procedure RzBmpButtonChgPassWordClick(Sender: TObject);procedure RzBmpButtonAutoLoginClick(Sender: TObject);procedure CloseTimerTimer(Sender: TObject);procedure ImageMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);procedure RzBmpButtonMinClick(Sender: TObject);procedure TreeViewClick(Sender: TObject);procedure TimerReakSkinTimer(Sender: TObject);procedure RzBmpButtonUpgradeClick(Sender: TObject);private{ Private declarations }procedure CreateUlr(sCreateUlrName: string);procedure DecodeMessagePacket(datablock: string);procedure ChgButtonStatus(btStatus: Byte);procedure ReleaseClient(sDirectory: string; GameZone: TGameZone);
//    function RunApp(AppName: string; I: Integer): Integer;procedure OnProgramException(Sender: TObject; E: Exception);function GetProcesses: Boolean;function GetModules(ProcessID: DWORD): Boolean;procedure ReadSkin;function SearchMirClient(Path: string): Boolean;procedure LoadUserConfig;procedure SaveUserConfig;public{ Public declarations }procedure SendGetRandomCode;procedure SendUpdateAccount(ue: TUserEntry; ua: TUserEntryAdd; nRandomCode: Integer);procedure SendGetBackPassword(sAccount, sQuest1, sAnswer1,sQuest2, sAnswer2, sBirthDay: string);procedure SendChgPw(sAccount, sPasswd, sNewPasswd: string);procedure SendCSocket(sendstr: string);procedure LoadListToBox();procedure ProcessMessage(var Msg: TMsg; var Handled: Boolean);procedure MyMessage(var MsgData: TWmCopyData); message WM_COPYDATA;end;varfrmMain: TfrmMain;MirClient: TMemoryStream;WebBrowser: TWebBrowser;
function CheckLegendPath(Path: string): Boolean;
function CheckMirPath(Path: string): Boolean;
function CheckFullPath(Path: string): Boolean;
procedure LoopFiles(Path, Mask: string; SubDir: TStrings);
function GetDrives: string;
function RunApp(AppName: string): Integer;
function SearchPath: Boolean;
implementation
uses EncryptUnit, HUtil32, LNewAccount, LChgPassword, LGetBackPassword {, SecrchInfoMain},LEditGame, LUpgrade, { CMain, NPCDialog, NPCMain,} CheckPrevious, ZLibEx;
constR_MyRootKey = HKEY_LOCAL_MACHINE; //注册表根键R_MySubKey = '\SOFTWARE\cqfir\Legend of mir'; //注册表子键R_SndaSubKey = '\SOFTWARE\snda\Legend of mir';R_Key = 'Path';
{$R *.dfm}procedure TSearchThread.Execute;
varDriverList: string;I, Len: Integer;
beginDriverList := GetDrives; //得到可写的磁盘列表 //遍历每个磁盘驱动器Len := Length(DriverList);for I := 1 to Len do beging_SearchList.Add(DriverList[I] + ':\');end;while (not Terminated) and (not SearchPath) and (not g_boClose) do beginend;
end;constructor TSearchThread.Create(CreateSuspended: Boolean);
begininherited;end;destructor TSearchThread.Destroy;
begininherited;
end;function ReadRegKey(const iMode: Integer; const sPath,sKeyName: string; var sResult: string): Boolean;
varrRegObject: TRegistry;
beginrRegObject := TRegistry.Create;Result := False;trywith rRegObject do beginRootKey := R_MyRootKey;if OpenKey(sPath, True) then begincase iMode of1: sResult := Trim(ReadString(sKeyName));2: sResult := IntToStr(ReadInteger(sKeyName));//3: sResult := ReadBinaryData(sKeyName, Buffer, BufSize);end;if sResult = '' then Result := False else Result := True;endelseResult := False;CloseKey;end;finallyrRegObject.Free;end;
end;
//_____________________________________________________________________//function WriteRegKey(const iMode: Integer; const sPath, sKeyName,sKeyValue: string): Boolean;
varrRegObject: TRegistry;bData: Byte;
beginrRegObject := TRegistry.Create;trywith rRegObject do beginRootKey := R_MyRootKey;if OpenKey(sPath, True) then begincase iMode of1: WriteString(sKeyName, sKeyValue);2: WriteInteger(sKeyName, StrToInt(sKeyValue));3: WriteBinaryData(sKeyName, bData, 1);end;Result := True;endelseResult := False;CloseKey;end;finallyrRegObject.Free;end;
end;
//_____________________________________________________________________//function SelectDirCB(Wnd: Hwnd; uMsg: UINT; LPARAM, lpData: LPARAM): Integer stdcall;
beginif (uMsg = BFFM_INITIALIZED) and (lpData <> 0) thenSendMessage(Wnd, BFFM_SETSELECTION, Integer(True), lpData);Result := 0;
end;function SelectDirectory(const Caption: string; const Root: WideString;var Directory: string; Owner: THandle): Boolean;
varWindowList: Pointer;BrowseInfo: TBrowseInfo;Buffer: PChar;RootItemIDList, ItemIDList: PItemIDList;ShellMalloc: IMalloc;IDesktopFolder: IShellFolder;Eaten, Flags: LongWord;
beginResult := False;if not DirectoryExists(Directory) thenDirectory := '';FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then beginBuffer := ShellMalloc.Alloc(MAX_PATH);tryRootItemIDList := nil;if Root <> '' then beginSHGetDesktopFolder(IDesktopFolder);IDesktopFolder.ParseDisplayName(Application.Handle, nil,POleStr(Root), Eaten, RootItemIDList, Flags);end;with BrowseInfo do beginhwndOwner := Owner;pidlRoot := RootItemIDList;pszDisplayName := Buffer;lpszTitle := PChar(Caption);ulFlags := BIF_RETURNONLYFSDIRS;if Directory <> '' then beginlpfn := SelectDirCB;LPARAM := Integer(PChar(Directory));end;end;WindowList := DisableTaskWindows(0);tryItemIDList := ShBrowseForFolder(BrowseInfo);finallyEnableTaskWindows(WindowList);end;Result := ItemIDList <> nil;if Result then beginShGetPathFromIDList(ItemIDList, Buffer);ShellMalloc.Free(ItemIDList);Directory := Buffer;end;finallyShellMalloc.Free(Buffer);end;end;
end;
//_____________________________________________________________________//function AddString(S: string): string;
beginResult := S;if S[Length(S)] <> '\' then Result := S + '\';
end;//获取当前的硬盘所有的盘符
{Lbl_DriveType:Tlabel;DriveType:WORD; //定义驱动器类型变量DriveType:=GetDriveType(RootPathName); //获得RootPathName所对应的磁盘驱动器信息case DriveType ofDRIVE_REMOVABLE:Lbl_DriveType.Caption:= '软盘驱动器';DRIVE_FIXED : Lbl_DriveType.Caption:= '硬盘驱动器';DRIVE_REMOTE: Lbl_DriveType.Caption:= '网络驱动器';DRIVE_CDROM: Lbl_DriveType.Caption:= '光盘驱动器';DRIVE_RAMDISK: Lbl_DriveType.Caption:= '内存虚拟盘';end; //将该磁盘信息显示在Lbl_DriveType中}function GetDrives: string;
varDiskType: Word;D: Char;Str: string;I: Integer;
beginfor I := 0 to 25 do //遍历26个字母beginD := Chr(I + 65);Str := D + ':';DiskType := GetDriveType(PChar(Str));//得到本地磁盘和网络盘if (DiskType = DRIVE_FIXED) {or (DiskType = DRIVE_REMOTE)} thenResult := Result + D;end;
end;{ 遍历目录 }
{
procedure LoopFiles(Path, Mask: string);
varI, Count: Integer;Fn, Ext: string;SubDir: TStrings;SearchRec: TSearchRec;Msg: TMsg;function IsValidDir(SearchRec: TSearchRec): Integer;beginif (SearchRec.Attr <> 16) and (SearchRec.Name <> '.') and(SearchRec.Name <> '..') thenResult := 0 //不是目录else if (SearchRec.Attr = 16) and (SearchRec.Name <> '.') and(SearchRec.Name <> '..') thenResult := 1 //不是根目录else Result := 2; //是根目录end;
beginSubDir := TStringList.Create;if (FindFirst(Path + '*.*', faDirectory, SearchRec) = 0) thenbeginrepeatif g_boClose then break;Application.ProcessMessages;if IsValidDir(SearchRec) = 1 then beginif not CheckMirPath(Path + SearchRec.Name + '\') then beginSubDir.Add(SearchRec.Name);FrmMain.LabelStatus.Caption := Path + SearchRec.Name;end else beging_sMirPath := Path + SearchRec.Name + '\';WriteRegKey(1, R_MySubKey, R_Key, g_sMirPath);Break;end;end;Sleep(1);until (FindNext(SearchRec) <> 0);end;FindClose(SearchRec);if not CheckMirPath(g_sMirPath) then beginCount := SubDir.Count - 1;for I := 0 to Count do beginif g_boClose then break;LoopFiles(Path + SubDir.Strings[I] + '\', Mask);end;end;FreeAndNil(SubDir);
end;}//缩短显示不下的长路径名function FormatPath(APath: string; Width: Integer): string;
varSLen: Integer;i, j: Integer;TString: string;
beginSLen := Length(APath);if (SLen <= Width) or (Width <= 6) thenbeginResult := APath;Exitendelsebegini := SLen;TString := APath;for j := 1 to 2 dobeginwhile (TString[i] <> '\') and (SLen - i < Width - 8) doi := i - 1;i := i - 1;end;for j := SLen - i - 1 downto 0 doTString[Width - j] := TString[SLen - j];for j := SLen - i to SLen - i + 2 doTString[Width - j] := '.';Delete(TString, Width + 1, 255);Result := TString;end;
end;procedure LoopFiles(Path, Mask: string; SubDir: TStrings);
varI, Count: Integer;Fn, Ext, FullPath: string;SearchRec: TSearchRec;Msg: TMsg;function IsValidDir(SearchRec: TSearchRec): Integer;beginif (SearchRec.Attr <> 16) and (SearchRec.Name <> '.') and(SearchRec.Name <> '..') thenResult := 0 //不是目录else if (SearchRec.Attr = 16) and (SearchRec.Name <> '.') and(SearchRec.Name <> '..') thenResult := 1 //不是根目录else Result := 2; //是根目录end;
beginif (FindFirst(Path + '*.*', faDirectory, SearchRec) = 0) then beginrepeatif g_boClose then break;Application.ProcessMessages;if IsValidDir(SearchRec) = 1 then beginFullPath := Path + SearchRec.Name + '\';if not CheckFullPath(FullPath) then begin//if CheckLegendPath(FullPath) thenif CheckLegendPath(FullPath) theng_LegendPathList.Add(FullPath);SubDir.Add(FullPath);FrmMain.LabelStatus.Caption := FormatPath(FullPath, 40);{if Length(FullPath) > 30 then beginFrmMain.LabelStatus.Caption := ExtractShortPathName(FullPath);end else beginFrmMain.LabelStatus.Caption := FullPath;end; }end else beging_sMirPath := FullPath;WriteRegKey(1, R_MySubKey, R_Key, g_sMirPath);Break;end;end;Sleep(1);until (FindNext(SearchRec) <> 0);end;FindClose(SearchRec);
end;function CheckLegendPath(Path: string): Boolean;
beginResult := (DirectoryExists(Path + 'Data')) and(DirectoryExists(Path + 'Map')) and(DirectoryExists(Path + 'Wav'));
end;function CheckFullPath(Path: string): Boolean;
beginResult := (DirectoryExists(Path + 'Data')) and(DirectoryExists(Path + 'Map')) and(DirectoryExists(Path + 'Wav')) and(not FileExists(Path + 'Data\ChrSel_16.wil')) and(not FileExists(Path + 'Data\Prguse_16.wil')) and(not FileExists(Path + 'Data\Prguse2_16.wil')) and(not FileExists(Path + 'Data\Prguse3_16.wil'));
end;function CheckMirPath(Path: string): Boolean;
varsKeyValue: string;
beginif CheckLegendPath(Path) then beging_sMirPath := Path;Result := True;end else beginif ReadRegKey(1, R_MySubKey, R_Key, sKeyValue) then beginif CheckLegendPath(sKeyValue) then beging_sMirPath := sKeyValue;Result := True;Exit;end;end;if ReadRegKey(1, R_SndaSubKey, R_Key, sKeyValue) then beginif CheckLegendPath(sKeyValue) then beging_sMirPath := sKeyValue;WriteRegKey(1, R_MySubKey, R_Key, g_sMirPath);Result := True;Exit;end;end;Result := False;end;
end;function SearchPath: Boolean;
varI: Integer;SubDir: TStrings;
beginResult := False;SubDir := TStringList.Create;for I := 0 to g_SearchList.Count - 1 do beginLoopFiles(g_SearchList[I], '*.*', SubDir);if g_boClose or CheckFullPath(g_sMirPath) then beginbreak;end;end;if not CheckFullPath(g_sMirPath) then beging_SearchList.Clear;g_SearchList.AddStrings(SubDir);end else Result := True;FreeAndNil(SubDir);
end;function TFrmMain.SearchMirClient(Path: string): Boolean;
varDriverList: string;sKeyValue: string;I, Len: Integer;
beginResult := False;if not CheckLegendPath(Path) then beginif ReadRegKey(1, R_MySubKey, R_Key, sKeyValue) then beginif CheckLegendPath(sKeyValue) then beging_sMirPath := sKeyValue;Result := True;Exit;end;end;if ReadRegKey(1, R_SndaSubKey, R_Key, sKeyValue) then beginif CheckLegendPath(sKeyValue) then beging_sMirPath := sKeyValue;WriteRegKey(1, R_MySubKey, R_Key, g_sMirPath);Result := True;Exit;end;end;DriverList := GetDrives; //得到可写的磁盘列表 //遍历每个磁盘驱动器Len := Length(DriverList);for I := 1 to Len do beging_SearchList.Add(DriverList[I] + ':\');end;while (not SearchPath) and (not g_boClose) do beginend;if (not CheckMirPath(g_sMirPath)) and (g_LegendPathList.Count > 0) then beging_sMirPath := g_LegendPathList.Strings[0];end;Result := CheckLegendPath(g_sMirPath);{DriverList := GetDrives; //得到可写的磁盘列表Len := Length(DriverList);for I := Len downto 1 do begin //遍历每个磁盘驱动器tryLoopFiles(DriverList[I] + ':\', '*.*');if CheckMirPath(g_sMirPath) then beginResult := True;Break;end;exceptend;if g_boClose then break;end;}end else beging_sMirPath := Path;if not ReadRegKey(1, R_MySubKey, R_Key, sKeyValue) then beginWriteRegKey(1, R_MySubKey, R_Key, g_sMirPath);end else beginif not CheckLegendPath(sKeyValue) then beginWriteRegKey(1, R_MySubKey, R_Key, g_sMirPath);end;end;Result := True;end;
end;procedure TfrmMain.ProcessMessage(var Msg: TMsg; var Handled: Boolean);
beginif Msg.message = WM_SENDPROCMSG then begin//    ShowMessage('asfd');Handled := True;end;
end;procedure TfrmMain.MyMessage(var MsgData: TWmCopyData);
varI, nHandle: Integer;sData: string;wIdent, wRecog: Word;
beginif not g_boClose then beginwIdent := HiWord(MsgData.From);wRecog := LoWord(MsgData.From);sData := StrPas(MsgData.CopyDataStruct^.lpData);case wIdent ofCM_HANDLE: beginnHandle := Str_ToInt(sData, 0);for I := 0 to g_ClientHandleList.Count - 1 do beginif nHandle = Integer(g_ClientHandleList.Items[I]) then beginExit;end;end;g_ClientHandleList.Add(Pointer(nHandle));//Showmessage('CM_HANDLE:'+IntToStr(nHandle));end;CM_QUIT: beginnHandle := Str_ToInt(sData, 0);//Showmessage('CM_QUIT:'+IntToStr(nHandle));for I := 0 to g_ClientHandleList.Count - 1 do beginif nHandle = Integer(g_ClientHandleList.Items[I]) then beging_ClientHandleList.Delete(I);Break;end;end;if IsIconic(Application.Handle) thenShowWindow(Application.Handle, SW_RESTORE);SetForegroundWindow(Application.Handle);end;end;end;
end;procedure TfrmMain.CreateUlr(sCreateUlrName: string); //创建快捷方式
varShLink: IShellLink;PFile: IPersistFile;FileName: string;WFileName: WideString;Reg: TRegIniFile;AnObj: IUnknown;UrlName: string;
beginUrlName := Trim(sCreateUlrName);if UrlName <> '' then beginAnObj := CreateComObject(CLSID_ShellLink);ShLink := AnObj as IShellLink;PFile := AnObj as IPersistFile;FileName := ParamStr(0);ShLink.SetPath(PChar(FileName));ShLink.SetWorkingDirectory(PChar(ExtractFilePath(FileName)));Reg := TRegIniFile.Create('Software\MicroSoft\Windows\CurrentVersion\Explorer');WFileName := Reg.ReadString('Shell Folders', 'Desktop', '') + '\' + UrlName + '.lnk';PFile.Save(PWChar(WFileName), True);end;
end;procedure TfrmMain.SendCSocket(sendstr: string);
varsSendText: string;
beginif ClientSocket.Socket.Connected then begin  //是否被连接sSendText := '#' + IntToStr(btCode) + sendstr + '!'; //btcode =1  #+btcode+sendstr+!ClientSocket.Socket.SendText('#' + IntToStr(btCode) + sendstr + '!');Inc(btCode);//+1if btCode >= 10 then btCode := 1;//>=10 则 赋值1end;
end;procedure TfrmMain.SendChgPw(sAccount, sPasswd, sNewPasswd: string); //发送修改密码
varMsg: TDefaultMessage;
beginMsg := MakeDefaultMsg(CM_CHANGEPASSWORD, 0, 0, 0, 0);//修改密码SendCSocket(EncodeMessage(Msg) + EncodeString(sAccount + #9 + sPasswd + #9 + sNewPasswd));
end;procedure TfrmMain.SendGetBackPassword(sAccount, sQuest1, sAnswer1,sQuest2, sAnswer2, sBirthDay: string); //发送找回密码
varMsg: TDefaultMessage;
beginMsg := MakeDefaultMsg(CM_GETBACKPASSWORD, 0, 0, 0, 0);//知足找回密码消息SendCSocket(EncodeMessage(Msg) + EncodeString(sAccount + #9 + sQuest1 + #9 + sAnswer1 + #9 + sQuest2 + #9 + sAnswer2 + #9 + sBirthDay));//消息代码 + 编码字符串 tab分割参数
end;procedure TfrmMain.SendGetRandomCode;
varMsg: TDefaultMessage;
beginMsg := MakeDefaultMsg(CM_RANDOMCODE, 0, 0, 0, 0); //make 一个默认消息SendCSocket(EncodeMessage(Msg)); //加密消息 发送消息
end;procedure TfrmMain.SendUpdateAccount(ue: TUserEntry; ua: TUserEntryAdd; nRandomCode: Integer); //发送新建账号
varMsg: TDefaultMessage;  //发送更新用户 新建用户
beginsMakeNewAccount := ue.sAccount;//全局变量Msg := MakeDefaultMsg(CM_ADDNEWUSER, nRandomCode, 0, 0, 0);//发送消息SendCSocket(EncodeMessage(Msg) + EncodeBuffer(@ue, SizeOf(TUserEntry)) + EncodeBuffer(@ua, SizeOf(TUserEntryAdd))); //329//发送 消息码+编码缓冲区ue+编码缓冲区ua
end;procedure TfrmMain.TimerTimer(Sender: TObject);
varStr, data: string;len, I, n, mcnt: Integer;
beginif boBusy then Exit;boBusy := True;trysBufferStr := sBufferStr + sSocStr;sSocStr := '';if sBufferStr <> '' then beginmcnt := 0;while Length(sBufferStr) >= 2 do beginif Pos('!', sBufferStr) <= 0 then Break;sBufferStr := ArrestStringEx(sBufferStr, '#', '!', data);if data <> '' then beginDecodeMessagePacket(data);end elseif Pos('!', sBufferStr) = 0 thenBreak;end;end;{if frmNewAccount.Visible then beginfrmNewAccount.LabelRandomCode.Caption := g_sRandomCode;end;}finallyboBusy := False;end;
end;procedure TfrmMain.TreeViewClick(Sender: TObject);
varTreeNode: TTreeNode;GameZone: TGameZone;sServerAddr: string;sServerPort: string;
beging_SelGameZone := nil;TreeNode := TreeView.Selected;if (TreeNode = nil) or (TreeNode.Parent = nil) then begin//Showmessage('TreeNode.Parent = nil');Exit;end;g_SelGameZone := TGameZone(TreeNode.Data);tryif not g_SelGameZone.Connected then beginClientSocket.Active := False;ClientSocket.Host := '';ClientSocket.Address := '';if g_SelGameZone.Encrypt then beginsServerAddr := DeCodeString(g_SelGameZone.GameHost);sServerPort := DeCodeString(g_SelGameZone.GameIPPort);end else beginsServerAddr := g_SelGameZone.GameHost;sServerPort := g_SelGameZone.GameIPPort;end;if IsIpAddr(sServerAddr) then beginClientSocket.Address := sServerAddr;end else beginClientSocket.Host := sServerAddr;end;ClientSocket.Port := Str_ToInt(sServerPort, 7000);ClientSocket.Active := True;end else beging_boClientSocketConnect := True;LabelStatus.Font.Color := g_GameLoginConfig.LabelConnectColor;LabelStatus.Caption := sClientConnect;RzBmpButtonFullScreenStart.Enabled := True;RzBmpButtonStart.Enabled := True;RzBmpButtonAutoLogin.Enabled := True;RzBmpButtonNewAccount.Enabled := True;RzBmpButtonGetBakPassWord.Enabled := True;RzBmpButtonChgPassWord.Enabled := True;end;//WebBrowser.Height := g_nWebHeiht;//WebBrowser.Width := g_WebBrowser.Width;WebBrowser.Navigate(g_SelGameZone.NoticeUrl);//WebBrowser.Width := g_WebBrowser.Width;{Showmessage(IntToStr(WebBrowser.Width));Showmessage(IntToStr(WebBrowser.Height));}exceptend;
end;procedure TfrmMain.DecodeMessagePacket(datablock: string);
varhead, body, body2, tagstr, data, rdstr, Str: string;Msg: TDefaultMessage;smsg: TShortMessage;mbw: TMessageBodyW;desc: TCharDesc;wl: TMessageBodyWL;featureEx: word;L, I, j, n, BLKSize, param, sound, cltime, svtime: Integer;tempb: Boolean;
beginif datablock[1] = '+' then Exit;if Length(datablock) < DEFBLOCKSIZE then Exit;head := Copy(datablock, 1, DEFBLOCKSIZE);body := Copy(datablock, DEFBLOCKSIZE + 1, Length(datablock) - DEFBLOCKSIZE);Msg := DecodeMessage(head);case Msg.Ident ofSM_NEWID_SUCCESS: beginApplication.MessageBox('您的帐号创建成功。' + #13 +'请妥善保管您的帐号和密码,' + #13 + '并且不要因任何原因把帐号和密码告诉任何其他人。' + #13 +'如果忘记了密码,你可以通过我们的主页重新找回。', '提示信息', MB_OK);frmNewAccount.Close;end;SM_NEWID_FAIL: begincase Msg.Recog of0: beginApplication.MessageBox(PChar('帐号 "' + sMakeNewAccount + '" 已被其他的玩家使用了。' + #13 +'请选择其它帐号名注册。'), '提示信息', MB_OK);end;1: beginApplication.MessageBox('验证码输入错误,请重新输入!!!', '提示信息', MB_OK);//frmNewAccount.EditRandomCode.SetFocus;end;-2: Application.MessageBox('此帐号名被禁止使用!', '提示信息', MB_OK);else Application.MessageBox(PChar('帐号创建失败,请确认帐号是否包括空格、及非法字符!Code: ' + IntToStr(Msg.Recog)), '提示信息', MB_OK);end;frmNewAccount.ButtonOK.Enabled := True;Exit;end;SM_RANDOMCODE: beginend;SM_CHGPASSWD_SUCCESS: beginApplication.MessageBox('密码修改成功。', '提示信息', MB_OK);{frmChangePassword.ChgEditAccount.Text:='';frmChangePassword.ChgEditPassword.Text:='';frmChangePassword.ChgEditConfirm.Text:='';frmChangePassword.ChgEditNewPassword.Text:='';}frmChangePassword.ButtonOK.Enabled := False;//frmNewAccount.Close;Exit;end;SM_CHGPASSWD_FAIL: begincase Msg.Recog of0: Application.MessageBox('输入的帐号不存在!!!', '提示信息', MB_OK);-1: Application.MessageBox('输入的原始密码不正确!', '提示信息', MB_OK);-2: Application.MessageBox('此帐号被锁定!', '提示信息', MB_OK);else Application.MessageBox('输入的新密码长度小于四位!', '提示信息', MB_OK);end;frmChangePassword.ButtonOK.Enabled := True;Exit;end;SM_GETBACKPASSWD_SUCCESS: beginfrmGetBackPassword.EditPassword.Text := DecodeString(body);Application.MessageBox(PChar('密码找回成功。'), '提示信息', MB_OK);Exit;end;SM_GETBACKPASSWD_FAIL: begincase Msg.Recog of0: Application.MessageBox('输入的帐号不存在!!!', '提示信息', MB_OK + MB_ICONERROR);-1: Application.MessageBox('问题答案不正确!!!', '提示信息', MB_OK + MB_ICONERROR);-2: Application.MessageBox(PChar('此帐号被锁定!!!' + #13 + '请稍候三分钟再重新找回。'), '提示信息', MB_OK + MB_ICONERROR);-3: Application.MessageBox('答案输入不正确!!!', '提示信息', MB_OK + MB_ICONERROR);else Application.MessageBox('未知错误!', '提示信息', MB_OK + MB_ICONERROR);end;frmGetBackPassword.ButtonOK.Enabled := True;Exit;end;end;
end;procedure TfrmMain.ClientSocketConnect(Sender: TObject;Socket: TCustomWinSocket);
beginif g_SelGameZone <> nil then beging_SelGameZone.GameIPaddr := Socket.RemoteAddress;g_SelGameZone.Connected := True;end;//ChgButtonStatus(0);g_boClientSocketConnect := True;LabelStatus.Font.Color := g_GameLoginConfig.LabelConnectColor;//LabelStatus.Font.Color := clLime;LabelStatus.Caption := sClientConnect;//frmGetBackPassword.LabelStatus.Caption := sClientConnect;//frmNewAccount.LabelStatus.Caption := sClientConnect;//frmChangePassword.LabelStatus.Caption := sClientConnect;RzBmpButtonFullScreenStart.Enabled := True;RzBmpButtonStart.Enabled := True;RzBmpButtonAutoLogin.Enabled := True;RzBmpButtonNewAccount.Enabled := True;RzBmpButtonGetBakPassWord.Enabled := True;RzBmpButtonChgPassWord.Enabled := True;
end;procedure TfrmMain.ClientSocketConnecting(Sender: TObject;Socket: TCustomWinSocket);
begin//ChgButtonStatus(1);g_boClientSocketConnect := False;LabelStatus.Font.Color := g_GameLoginConfig.LabelConnectingColor; //clFuchsia;LabelStatus.Caption := sClientConnecting;frmGetBackPassword.LabelStatus.Caption := sClientConnecting;//frmNewAccount.LabelStatus.Caption := sClientConnecting;//frmChangePassword.LabelStatus.Caption := sClientConnecting;RzBmpButtonFullScreenStart.Enabled := False;RzBmpButtonStart.Enabled := False;RzBmpButtonAutoLogin.Enabled := False;RzBmpButtonNewAccount.Enabled := False;RzBmpButtonGetBakPassWord.Enabled := False;RzBmpButtonChgPassWord.Enabled := False;
end;procedure TfrmMain.ClientSocketDisconnect(Sender: TObject;Socket: TCustomWinSocket);
begin//ChgButtonStatus(2);g_boClientSocketConnect := False;if not g_SelGameZone.Connected then beginLabelStatus.Font.Color := g_GameLoginConfig.LabelDisconnectColor; //clYellow;LabelStatus.Caption := sClientDisconnect;//frmGetBackPassword.LabelStatus.Caption := sClientDisconnect;//frmNewAccount.LabelStatus.Caption := sClientDisconnect;//frmChangePassword.LabelStatus.Caption := sClientDisconnect;RzBmpButtonFullScreenStart.Enabled := False;RzBmpButtonStart.Enabled := False;RzBmpButtonAutoLogin.Enabled := False;RzBmpButtonNewAccount.Enabled := False;RzBmpButtonGetBakPassWord.Enabled := False;RzBmpButtonChgPassWord.Enabled := False;end;
end;procedure TfrmMain.ClientSocketError(Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer);
begin//ChgButtonStatus(2);ErrorCode := 0;Socket.Close;
end;procedure TfrmMain.ClientSocketRead(Sender: TObject;Socket: TCustomWinSocket);
varn: Integer;data, data2: string;
begindata := Socket.ReceiveText;n := Pos('*', data);if n > 0 then begindata2 := Copy(data, 1, n - 1);data := data2 + Copy(data, n + 1, Length(data));ClientSocket.Socket.SendText('*');end;sSocStr := sSocStr + data;
end;procedure TfrmMain.OnProgramException(Sender: TObject; E: Exception);
beginDebugOutStr(E.Message);
end;procedure TFrmMain.LoadUserConfig;
varConf: TIniFile;
beginConf := TIniFile.Create(g_sSelfFilePath + 'User.ini');//RzCheckBoxWindowMode.Checked := Conf.ReadBool('Settings', 'WindowMode', False);//ComboBoxScreenMode.ItemIndex := Conf.ReadInteger('Settings', 'ScreenMode', 0);ComboBox.ItemIndex := Conf.ReadInteger('Settings', 'ScreenMode', 0);Conf.Free;
end;procedure TFrmMain.SaveUserConfig;
varConf: TIniFile;
beginConf := TIniFile.Create(g_sSelfFilePath + 'User.ini');//Conf.WriteBool('Settings', 'WindowMode', RzCheckBoxWindowMode.Checked);//Conf.WriteInteger('Settings', 'ScreenMode', ComboBoxScreenMode.ItemIndex);Conf.WriteInteger('Settings', 'ScreenMode', ComboBox.ItemIndex);Conf.Free;
end;procedure TfrmMain.FormCreate(Sender: TObject);varBatchFileName: string;sCopyFile: string;MemoryStream: TMemoryStream;//FileStream: TMemoryStream;PlugStream: TMemoryStream;Config: TConfig;sText: string;nCount: Integer;nCount1: Integer;Buffer: Pointer;OutBuf: Pointer;OutBytes: Integer;SrcP: Pointer;nLen: Integer;//JPE: TJpegImage;Bitmap: TBitmap;I: Integer;
beginApplication.ShowMainForm := False;//隐藏主窗口g_sSelfFileName := ExtractFileName(Application.ExeName);//自身文件名g_sSelfFilePath := ExtractFilePath(Application.ExeName);//自身路径g_SearchList := TStringList.Create;//搜索列表g_LegendPathList := TStringList.Create;//传奇客户端路径g_ClientHandleList := TList.Create;//客户端句柄WebBrowser := TWebBrowser.Create(Self);//游览器g_ComponentList.Add(RzBmpButtonFullScreenStart);//全屏启动g_ComponentList.Add(RzBmpButtonEditGameList);//编辑游戏g_ComponentList.Add(RzBmpButtonHomePage);//官方主页g_ComponentList.Add(RzBmpButtonAutoLogin);//脱机登陆g_ComponentList.Add(RzBmpButtonUpgrade);//游戏更新g_ComponentList.Add(RzBmpButtonStart);//窗口登陆g_ComponentList.Add(RzBmpButtonNewAccount);//帐号注册g_ComponentList.Add(RzBmpButtonGetBakPassWord);//密码找回g_ComponentList.Add(RzBmpButtonChgPassWord);//修改密码g_ComponentList.Add(RzBmpButtonExitGame);//退出游戏g_ComponentList.Add(RzBmpButtonMin);//最小化g_ComponentList.Add(RzBmpButtonClose);//关闭g_ComponentList.Add(TreeView);//列表g_ComponentList.Add(WebBrowser);//游览器g_ComponentList.Add(LabelStatus);//状态g_ComponentList.Add(ComboBox);//分辨率MirClient := nil;//内存变量
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}MirClient := TMemoryStream.Create;//创建MemoryStream := TMemoryStream.Create; //创建trynLen := SizeOf(TGameLoginConfig);//获取游戏配置大小MemoryStream.LoadFromFile(Application.ExeName);//载入exeMemoryStream.Seek(-nLen, soFromEnd);//移动底部 倒退配置大小MemoryStream.Read(g_GameLoginConfig, nLen);//读取到内存  配置文件中for I := 0 to Length(g_GameLoginConfig.ComponentImages) - 1 do beginInc(nLen, g_GameLoginConfig.ComponentImages[I].UpSize); //图片 大小Inc(nLen, g_GameLoginConfig.ComponentImages[I].HotSize); //图片大小Inc(nLen, g_GameLoginConfig.ComponentImages[I].DownSize);//大小Inc(nLen, g_GameLoginConfig.ComponentImages[I].Disabled);//大小end;{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}//读取界面数据MemoryStream.Seek(-nLen, soFromEnd);//移动GetMem(g_Buffer, nLen - SizeOf(TGameLoginConfig));//分配内存MemoryStream.Read(g_Buffer^, nLen - SizeOf(TGameLoginConfig));//读取
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}MemoryStream.Seek(-(nLen + SizeOf(Integer)), soFromEnd); //移动MemoryStream.Read(nCount, SizeOf(Integer));//读取整形countMemoryStream.Seek(-(nLen + SizeOf(Integer) + nCount), soFromEnd);//再移动GetMem(Buffer, nCount);//分配内存tryMemoryStream.Read(Buffer^, nCount); //读到buffer中DecompressBuf(Buffer, nCount, 0, OutBuf, OutBytes);//解压指针finallyFreeMem(Buffer);//释放内存end;Move(OutBuf^, Config, OutBytes);//将解压后的配置 移动到 ConfigFreeMem(OutBuf);//释放内存GetMem(Buffer, Config.nClientSize);//分配内存tryMemoryStream.Seek(Config.nClientPos, soFromBeginning);//客户端的位置MemoryStream.Read(Buffer^, Config.nClientSize);//读取到bufferMirClient.Write(Buffer^, Config.nClientSize);//将读取到的buffer写入到mirclient内存流中finallyFreeMem(Buffer);end;exceptend;MemoryStream.Free;{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}g_CreateUlrName := EncodeString(Config.sUlrName);//解码快捷方式名称g_sHomePage := EncodeString(Config.sHomePage);//解码地址g_sRemoteConfigAddress := EncodeString(Config.sConfigAddress);//解码配置地址g_sGameRemoteAddress := EncodeString(Config.sGameAddress);//解码游戏地址g_boClose := False;CreateUlr(DeCodeString(g_CreateUlrName));//创建快捷方式g_AllGameList := TGameZone.Create;//所有游戏列表g_GameList := TGameZone.Create();//游戏列表g_LocalGameList := TGameZone.Create();//本地列表//g_MessageDlg := TMessageDlg.Create(Owner);//g_NpcDlg := TNpcDlg.Create(Owner);//TimerReakSkin.Enabled := TRUE;ReadSkin;//读取皮肤if CheckMirPath(g_sSelfFilePath) then begin  //检查客户端路径{ g_MirsClient.sDirectory := g_sMirPath;g_MirsClient.sDirectory := g_sMirPath; }frmUpgradeDownload := TfrmUpgradeDownload.Create(Owner); //创建更新窗口frmUpgradeDownload.Open;//打开frmUpgradeDownload.Free;//释放{Self.Repaint;Self.Refresh; }end;LoadUserConfig;//载入配置if g_boNeedUpgradeSelf then beginCloseTimer.Enabled := True;end else beginTimerStart.Enabled := True;Application.ShowMainForm := True;end;//Image.RecreateRegion;{if g_boClose then beginApplication.ShowMainForm := False;CloseTimer.Enabled := True;end else beginTimerStart.Enabled := True;end;}
end;procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
varI: Integer;nHandle: Integer;
beging_boClose := True;for I := 0 to g_ClientHandleList.Count - 1 do beginnHandle := Integer(g_ClientHandleList.Items[I]);SendProgramMsg(nHandle, GL_QUIT, '');end;tryif not g_boClose theng_LocalGameList.SaveToFile(g_sLocalGameListFileName);g_GameList.Free;g_LocalGameList.Free;g_AllGameList.Free;WebBrowser.Free;g_ClientHandleList.Free;if MirClient <> nil then MirClient.Free;g_SearchList.Free;g_LegendPathList.Free;exceptend;
end;function TfrmMain.GetProcesses: Boolean;
varhSnap: THandle;ProcessEntry: TProcessEntry32;Proceed: Boolean;
beginResult := False;hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); //创建系统快照if hSnap <> -1 thenbeginProcessEntry.dwSize := SizeOf(TProcessEntry32); //先初始化 FProcessEntry32 的大小Proceed := Process32First(hSnap, ProcessEntry);while Proceed do beginwith ProcessEntry doif (CompareText(StrPas(szEXEFile), 'JS.UCU') = 0) then begin//CloseProcess(Th32ProcessID);Result := True;Break;end else beginif GetModules(Th32ProcessID) then beginResult := True;Break;end;end;{ with listview_pro.Items.Add dobeginCaption := szEXEFile;subitems.Add(IntToStr(Th32ProcessID));subitems.Add(IntToStr(th32ParentProcessID));subitems.Add(IntToStr(Th32ModuleID));subitems.Add(IntToStr(cntUsage));subitems.Add(IntToStr(cntThreads));subitems.Add(IntToStr(pcPriClassBase));end; }Proceed := Process32Next(hSnap, ProcessEntry);end;CloseHandle(hSnap);end;{elseShowMessage( 'Oops...' + SysErrorMessage(GetLastError)); }
end;function TfrmMain.GetModules(ProcessID: DWORD): Boolean;
var hSnap: THandle;ModuleEntry: TModuleEntry32;Proceed: Boolean;
beginResult := False;hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);if hSnap <> -1 thenbeginModuleEntry.dwSize := SizeOf(TModuleEntry32);Proceed := Module32First(hSnap, ModuleEntry);while Proceed dobeginwith ModuleEntry doif (CompareText(szModule, 'WINIO.DLL') = 0) or (CompareText(szModule, 'JSHJ.DLL') = 0) then begin//CloseProcess(ProcessID);Result := True;Break;end;{with listview_mod.Items.Add dobeginCaption := szModule;subitems.Add(ExtractFilePath(szEXEPath));subitems.Add(IntToStr(Th32ModuleID));subitems.Add(FloatToStr(ModBaseSize / 1024));subitems.Add(IntToStr(GlblCntUsage));end; }Proceed := Module32Next(hSnap, ModuleEntry);end;CloseHandle(hSnap);end;{elseShowMessage( 'Oops...' + SysErrorMessage(GetLastError));  }
end;function RunProgram(GameZone: TGameZone; sDirectory, sProgramFile, sHandle: string; dwWaitTime: LongWord; nScreenWidth, nScreenHegiht: Integer): LongWord;
varStartupInfo: TStartupInfo;sCommandLine: string;sCurDirectory: string;ProcessInfo: TProcessInformation;dwTick: LongWord;MirServer: TMirServer;
beginResult := 0;FillChar(StartupInfo, SizeOf(TStartupInfo), #0);{StartupInfo.cb:=SizeOf(TStartupInfo);StartupInfo.lpReserved:=nil;StartupInfo.lpDesktop:=nil;StartupInfo.lpTitle:=nil;StartupInfo.dwFillAttribute:=0;StartupInfo.cbReserved2:=0;StartupInfo.lpReserved2:=nil;}if GameZone.Encrypt then beginMirServer.sServeraddr := DeCodeString(GameZone.GameHost);MirServer.nServerPort := Str_ToInt(DeCodeString(GameZone.GameIPPort), 0);end else beginMirServer.sServeraddr := GameZone.GameHost;MirServer.nServerPort := Str_ToInt(GameZone.GameIPPort, 0);end;MirServer.sServerName := GameZone.ServerName;MirServer.boFullScreen := g_boFullScreen;MirServer.nScreenWidth := nScreenWidth;MirServer.nScreenHegiht := nScreenHegiht;GetStartupInfo(StartupInfo);StartupInfo.wShowWindow := SW_SHOW;StartupInfo.dwFlags := STARTF_USEFILLATTRIBUTE;StartupInfo.dwFillAttribute := FOREGROUND_INTENSITY or BACKGROUND_BLUE;sCommandLine := Format('%s%s %s %s', [sDirectory, sProgramFile, sHandle, EncodeBuffer(@MirServer, SizeOf(TMirServer))]);dwTick := GetTickCount;sCurDirectory := sDirectory;if not CreateProcess(nil, //lpApplicationName,PChar(sCommandLine), //lpCommandLine,nil, //lpProcessAttributes,nil, //lpThreadAttributes,True, //bInheritHandles,0, //dwCreationFlags,nil, //lpEnvironment,PChar(sCurDirectory), //lpCurrentDirectory,StartupInfo, //lpStartupInfo,ProcessInfo) then begin //lpProcessInformationResult := GetLastError();end;//Sleep(dwWaitTime);
end;procedure TfrmMain.RzBmpButtonFullScreenStartClick(Sender: TObject);
varI: Integer;nScreenWidth: Integer;nScreenHegiht: Integer;
beginif g_SelGameZone <> nil then beging_boFullScreen := Sender = RzBmpButtonFullScreenStart;FileSetAttr(g_sMirPath + g_sProgamFile, 0);tryMirClient.SaveToFile(g_sMirPath + g_sProgamFile);  // 释放 MirClient.dat 客户端文件exceptend;Application.Minimize; //自身最小化窗口//RunApp(g_sMirPath + g_sProgamFile); //启动客户端nScreenWidth := 800;nScreenHegiht := 600;case ComboBox.ItemIndex of0: beginnScreenWidth := 800;nScreenHegiht := 600;end;1: beginnScreenWidth := 1024;nScreenHegiht := 768;end;end;SaveUserConfig;RunProgram(g_SelGameZone, g_sMirPath, g_sProgamFile, IntToStr(Handle), 0, nScreenWidth, nScreenHegiht);end;
end;procedure TfrmMain.ChgButtonStatus(btStatus: Byte);
begin//RzBmpButtonStatus.Bitmaps.Up.LoadFromResourceName(HInstance, 'Connect');{case btStatus of0: beginConnectRes := TResourceStream.Create(HInstance, 'Connect', PChar('Bmp'));RzBmpButtonStatus.Bitmaps.Up.LoadFromStream(ConnectRes);ConnectRes.Free;end;1: beginConnectingRes := TResourceStream.Create(HInstance, 'Connecting', PChar('Bmp'));RzBmpButtonStatus.Bitmaps.Up.LoadFromStream(ConnectingRes);ConnectingRes.Free;end;2: beginDisconnectRes := TResourceStream.Create(HInstance, 'Disconnect', PChar('Bmp'));RzBmpButtonStatus.Bitmaps.Up.LoadFromStream(DisconnectRes);DisconnectRes.Free;end;end;}
end;procedure TfrmMain.RzBmpButtonCloseClick(Sender: TObject);
beginClose;
end;procedure TfrmMain.RzBmpButtonHomePageClick(Sender: TObject);
beginif g_SelGameZone = nil then Exit;ShellExecute(0, 'Open', PChar(g_SelGameZone.HomePage), nil, nil, SW_SHOWNORMAL);//打开网页
end;procedure TfrmMain.RzBmpButtonNewAccountClick(Sender: TObject);
beginfrmMain.SendGetRandomCode;//frmNewAccount.LabelStatus.Caption := MsgLabel.Caption;frmNewAccount.Open;
end;procedure TfrmMain.RzBmpButtonUpgradeClick(Sender: TObject);
begin
//升级代码也是假的
end;procedure TfrmMain.RzBmpButtonGetBakPassWordClick(Sender: TObject);
begin//frmGetBackPassword.LabelStatus.Caption := MsgLabel.Caption;frmGetBackPassword.Open;
end;procedure TfrmMain.RzBmpButtonChgPassWordClick(Sender: TObject);
begin//frmChangePassword.LabelStatus.Caption := MsgLabel.Caption;frmChangePassword.Open;
end;procedure TfrmMain.ReleaseClient(sDirectory: string; GameZone: TGameZone);{function HostToIP(Name: string; var Ip: string): Boolean;varwsdata: TWSAData;hostName: array[0..255] of char;hostEnt: PHostEnt;addr: PChar;beginWSAStartup($0101, wsdata);trygethostname(hostName, SizeOf(hostName));StrPCopy(hostName, Name);hostEnt := gethostbyname(hostName);if Assigned(hostEnt) thenif Assigned(hostEnt^.h_addr_list) then beginaddr := hostEnt^.h_addr_list^;if Assigned(addr) then beginIp := Format('%d.%d.%d.%d', [Byte(addr[0]),Byte(addr[1]), Byte(addr[2]), Byte(addr[3])]);Result := True;endelseResult := FALSE;endelseResult := FALSEelse beginResult := FALSE;end;finallyWSACleanup;endend; }
varRes: TResourceStream;//sIpAddr: string;Myinifile: TIniFile;sServerAddr: string;sServerPort: string;
beginFileSetAttr(sDirectory + g_sProgamFile, 0);tryMirClient.SaveToFile(sDirectory + g_sProgamFile);exceptend;{  Res := TResourceStream.Create(HInstance, 'MirClient', PChar('exe'));tryFileSetAttr(sDirectory + g_sProgamFile, 0);Res.SaveToFile(sDirectory + g_sProgamFile);exceptend;Res.Free;}{ FileSetAttr(sDirectory + g_sClientFile, 0);Res := TResourceStream.Create(HInstance, 'FirClient', PChar('dll'));tryRes.SaveToFile(sDirectory + g_sClientFile);Res.Free;Res := nil;exceptRes.Free;Res := nil;end;  }if GameZone.Encrypt then beginsServerAddr := DeCodeString(GameZone.GameHost);sServerPort := DeCodeString(GameZone.GameIPPort);end else beginsServerAddr := GameZone.GameHost;sServerPort := GameZone.GameIPPort;end;FileSetAttr(sDirectory + 'mir.ini', 0);Myinifile := TIniFile.Create(sDirectory + 'mir.ini');if Myinifile <> nil then beginMyinifile.WriteString('Setup', 'FontName', '宋体');Myinifile.WriteBool('Setup', 'FullScreen', g_boFullScreen);Myinifile.WriteString('Setup', 'Serveraddr', GameZone.GameIPaddr); //IP地址Myinifile.WriteString('Setup', 'ServerPort', sServerPort); //端口Myinifile.Free;end;{ FileSetAttr(sDirectory + 'ftp.ini', 0);Myinifile := TIniFile.Create(sDirectory + 'ftp.ini');if Myinifile <> nil then beginMyinifile.WriteInteger('Server', 'Servercount', 1);Myinifile.WriteString('Server', 'server1caption', GameZone.ServerName); //开门名称Myinifile.WriteString('Server', 'server1name', GameZone.ServerName); //服务器名称Myinifile.Free;end;   }{FileSetAttr(sDirectory + g_sProgamFile, 2);FileSetAttr(sDirectory + g_sClientFile, 2); }
end;function RunApp(AppName: string): Integer;
varSti: TStartupInfo;ProcessInfo: TProcessInformation;
beginFillMemory(@Sti, SizeOf(Sti), 0);Sti.wShowWindow := SW_SHOW;Sti.dwFlags := STARTF_USEFILLATTRIBUTE;Sti.dwFillAttribute := FOREGROUND_INTENSITY or BACKGROUND_BLUE;if CreateProcess(PChar(AppName), nil,nil, nil, False,0, nil, PChar(ExtractFilePath(AppName)),Sti, ProcessInfo) then beginResult := ProcessInfo.dwProcessId;end else Result := -1;
end;{procedure CopyFile(const Sour, Dest: string);
varFileOp: TSHFileOpStruct;
beginwith FileOp do beginWnd := FrmMain.HandLe;wFunc := FO_Copy; //更换此参数可实现拷贝和更名pFrom := PChar(Sour);pTo := PChar(Dest);fFlags := FOF_NoConfirmation;fAnyOperationsAborted := False;hNameMappings := nil;lpszProgressTitle := nilend;SHFileOperation(FileOp);
end;}//判断文件是否正在使用function IsFileInUse(FName: string): Boolean;
varHFileRes: HFILE;
beginResult := False;if not FileExists(FName) thenExit;HFileRes := CreateFile(PChar(FName), GENERIC_READ or GENERIC_WRITE, 0,nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);Result := (HFileRes = INVALID_HANDLE_VALUE);if not Result thenCloseHandle(HFileRes);
end;procedure TfrmMain.TimerStartTimer(Sender: TObject);
varI, n01: Integer;GameZone: TGameZone;TreeNode: TTreeNode;ChildTreeNode: TTreeNode;sFileName: string;//GameArea: pTGameArea;
beginTimerStart.Enabled := False;//ParamStr(1);if not CheckMirPath(g_sSelfFilePath) then beginif Application.MessageBox('目录不正确,是否自动搜索热血传奇客户端?','提示信息',MB_YESNO + MB_ICONQUESTION) = IDYES then beginif SearchMirClient(g_sSelfFilePath) then beginif IsFileInUse(g_sMirPath + g_sSelfFileName) then beginif Pos('.', g_sSelfFileName) > 0 then beging_sSelfFileName := Copy(g_sSelfFileName, 1, Pos('.', g_sSelfFileName) - 1);end;//g_sSelfFileName := Copy(g_sSelfFileName, 1, Length(g_sSelfFileName) - 4);//ChangeFileExt(ExtractFileName(sFileName),'');n01 := 0;while TRUE do beginsFileName := g_sMirPath + g_sSelfFileName + IntToStr(n01) + '.exe';if not FileExists(sFileName) then Break;end;g_sSelfFileName := g_sSelfFileName + IntToStr(n01) + '.exe';end else beginFileSetAttr(g_sMirPath + g_sSelfFileName, 0);DeleteFile(g_sMirPath + g_sSelfFileName);end;CopyFile(PChar(Application.ExeName), PChar(g_sMirPath + g_sSelfFileName), True); //复制自己RunApp(g_sMirPath + g_sSelfFileName); //启动Application.Terminate;Exit;end;end else beginif not SelectDirectory('请选择您的热血传奇客户端“Legend of mir2”目录', '', g_sMirPath, Handle) then beginClose;Exit;end;if (g_sMirPath <> '') and (g_sMirPath[Length(g_sMirPath)] <> '\') then g_sMirPath := g_sMirPath + '\';if not CheckMirPath(g_sMirPath) then beginClose;Exit;end else beginWriteRegKey(1, R_MySubKey, R_Key, g_sMirPath);if IsFileInUse(g_sMirPath + g_sSelfFileName) then beginif Pos('.', g_sSelfFileName) > 0 then beging_sSelfFileName := Copy(g_sSelfFileName, 1, Pos('.', g_sSelfFileName) - 1);end;//g_sSelfFileName := Copy(g_sSelfFileName, 1, Length(g_sSelfFileName) - 4);//ChangeFileExt(ExtractFileName(sFileName),'');n01 := 0;while TRUE do beginsFileName := g_sMirPath + g_sSelfFileName + IntToStr(n01) + '.exe';if not FileExists(sFileName) then Break;end;g_sSelfFileName := g_sSelfFileName + IntToStr(n01) + '.exe';end else beginFileSetAttr(g_sMirPath + g_sSelfFileName, 0);DeleteFile(g_sMirPath + g_sSelfFileName);end;CopyFile(PChar(Application.ExeName), PChar(g_sMirPath + g_sSelfFileName), True); //复制自己RunApp(g_sMirPath + g_sSelfFileName); //启动Application.Terminate;Exit;end;end;end;g_sLocalGameListFileName := g_sMirPath + 'LocalCqfir.Dat';Timer.Enabled := True;//g_GameList.LoadFromFile(g_sGameListFileName);g_LocalGameList.LoadFromFile(g_sLocalGameListFileName);LoadListToBox();TreeNode := TreeView.Items.GetFirstNode;if TreeNode <> nil then beginChildTreeNode := TreeNode.getFirstChild;if ChildTreeNode <> nil then beginTreeView.SetFocus;ChildTreeNode.Selected := True;ChildTreeNode.Focused := True;TreeViewClick(TreeView);end;end;
end;procedure TfrmMain.LoadListToBox();
varI, II: Integer;GameZone: TGameZone;ChildGameZone: TGameZone;TreeNode: TTreeNode;ChildTreeNode: TTreeNode;
beginTreeView.Items.Clear;g_AllGameList.Clear;g_AllGameList.Strings.AddStrings(g_GameList.Strings);g_AllGameList.Strings.AddStrings(g_LocalGameList.Strings);for I := 0 to g_AllGameList.Count - 1 do beginGameZone := g_AllGameList.Items[I];if GameZone.Count > 0 then beginTreeNode := TreeView.Items.AddObject(nil, GameZone.Caption, GameZone);TreeNode.HasChildren := True;//TreeNode.EndEdit(False);for II := 0 to GameZone.Count - 1 do beginChildGameZone := GameZone.Items[II];ChildTreeNode := TreeView.Items.AddChildObject(TreeNode, ChildGameZone.Caption, ChildGameZone);//TreeNode.Expand(ChildGameZone.Expand);//ChildTreeNode.EndEdit(False);//Showmessage(ChildGameZone.Caption);end;ChildTreeNode.Expand(ChildGameZone.Expand);end;end;
end;procedure TfrmMain.RzBmpButtonEditGameListClick(Sender: TObject);
beginfrmEditGame := TfrmEditGame.Create(Owner);//打开编辑列表frmEditGame.Open();frmEditGame.Free;
end;procedure TfrmMain.RzBmpButtonAutoLoginClick(Sender: TObject);
begin   //脱机登陆{tryif g_SelGameZone <> nil then beginfrmCMain := TfrmCMain.Create(Application);frmCMain.Open;Application.Minimize;end;exceptend; }
end;procedure TfrmMain.CloseTimerTimer(Sender: TObject);
varBatchFile: TextFile;BatchFileName: string;ProcessInfo: TProcessInformation;StartUpInfo: TStartupInfo;
beginCloseTimer.Enabled := False;BatchFileName := ExtractFilePath(ParamStr(0)) + '$$s$$.bat';FileSetAttr(BatchFileName, 0);DeleteFile(BatchFileName);AssignFile(BatchFile, BatchFileName);Rewrite(BatchFile);Writeln(BatchFile, ':tryn');Writeln(BatchFile, 'ren ' + g_sSelfFileName + ' ' + g_sSelfFileName + '.Del');Writeln(BatchFile, 'if exist "' + g_sSelfFileName + '.Del' + '"' + ' goto try');Writeln(BatchFile, 'if exist "' + g_sSelfFileName + '"' + ' goto tryn');Writeln(BatchFile, ':try');Writeln(BatchFile, 'del "' + g_sSelfFileName + '.Del' + '"');Writeln(BatchFile, 'if exist "' + g_sSelfFileName + '.Del' + '"' + ' goto try');Writeln(BatchFile, ':refren');Writeln(BatchFile, 'ren ' + g_sUpgradeSelfFileName + ' ' + g_sSelfFileName);Writeln(BatchFile, 'if not exist "' + g_sSelfFileName + '"' + ' goto refren');Writeln(BatchFile, 'start ' + g_sSelfFileName);Writeln(BatchFile, 'del %0');Writeln(BatchFile, 'exit');CloseFile(BatchFile);//FileSetAttr(BatchFileName, 2);FileSetAttr(ExtractFilePath(ParamStr(0)) + g_sSelfFileName, 0);FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;StartUpInfo.wShowWindow := SW_Hide;if CreateProcess(nil, PChar(BatchFileName), nil, nil,False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo,ProcessInfo) then beginCloseHandle(ProcessInfo.hThread);CloseHandle(ProcessInfo.hProcess);end;Close;
end;procedure TfrmMain.ImageMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
beginif Button = mbLeft then beginReleaseCapture;Perform(WM_SYSCOMMAND, $F012, 0);end;
end;procedure TfrmMain.RzBmpButtonMinClick(Sender: TObject);
beginApplication.Minimize;
end;procedure TfrmMain.ReadSkin;function IncPointer(Buffer: Pointer; Size: Integer): Pointer;beginResult := Pointer(Integer(Buffer) + Size);end;varI: Integer;nLen: Integer;Buffer: Pointer;ReadBuffer: Pointer;OutBuf: Pointer;OutBytes: Integer;Bitmap: TBitmap;FileStream: TMemoryStream;
beginBuffer := g_Buffer;FileStream := TMemoryStream.Create;Application.ProcessMessages;if g_GameLoginConfig.ComponentImages[0].UpSize > 0 then beginDecompressBuf(Buffer, g_GameLoginConfig.ComponentImages[0].UpSize, 0, OutBuf, OutBytes);Buffer := IncPointer(Buffer, g_GameLoginConfig.ComponentImages[0].UpSize);FileStream.Clear;FileStream.Write(OutBuf^, OutBytes);FileStream.Position := 0;FreeMem(OutBuf);//设置背景Bitmap := TBitmap.Create;Bitmap.LoadFromStream(FileStream);FileStream.Position := 0;//Bitmap.SaveToFile('Bitmap.bmp');ClientHeight := Bitmap.Height;ClientWidth := Bitmap.Width;Image.Picture.Bitmap.Assign(Bitmap);Image.Transparent := g_GameLoginConfig.Transparent;//Image.Picture.Bitmap.LoadFromStream(FileStream);//Image.Picture.Bitmap.TransparentColor := clBlack;//Image.Picture.Bitmap.Transparent := True;if Image.Transparent thenImage.RecreateRegion;Bitmap.Free;end;Application.ProcessMessages;
{------------------------------------------------------------------------------}//设置其他控件位置for I := 0 to Length(g_GameLoginConfig.ComponentConfigs) - 1 do beginApplication.ProcessMessages;if WebBrowser = g_ComponentList.Items[I] then beging_nWebHeiht := g_GameLoginConfig.ComponentConfigs[I].Height;g_WebBrowser := g_GameLoginConfig.ComponentConfigs[I];end else beginTWinControl(g_ComponentList.Items[I]).Left := g_GameLoginConfig.ComponentConfigs[I].Left;TWinControl(g_ComponentList.Items[I]).Top := g_GameLoginConfig.ComponentConfigs[I].Top;TWinControl(g_ComponentList.Items[I]).Width := g_GameLoginConfig.ComponentConfigs[I].Width;TWinControl(g_ComponentList.Items[I]).Height := g_GameLoginConfig.ComponentConfigs[I].Height;if TWinControl(g_ComponentList.Items[I]).Visible thenwith TWinControl(g_ComponentList.Items[I]) doSetBounds(Left, Top, Width, Height);end;TWinControl(g_ComponentList.Items[I]).Visible := g_GameLoginConfig.ComponentConfigs[I].Visible;end;//设置游览器位置WebBrowser.Left := g_WebBrowser.Left;WebBrowser.Top := g_WebBrowser.Top;WebBrowser.Width := g_WebBrowser.Width;WebBrowser.Height := g_WebBrowser.Height;WebBrowser.ParentWindow := Handle;with g_WebBrowser doWebBrowser.SetBounds(Left, Top, Width, Height);
//设置按钮图片for I := 1 to Length(g_GameLoginConfig.ComponentImages) - 1 do beginApplication.ProcessMessages;if TRzBmpButton(g_ComponentList.Items[I - 1]).Visible then beginif (g_GameLoginConfig.ComponentImages[I].UpSize > 0) and (TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Up <> nil) then beginFileStream.Clear;FileStream.Write(Buffer^, g_GameLoginConfig.ComponentImages[I].UpSize);Buffer := IncPointer(Buffer, g_GameLoginConfig.ComponentImages[I].UpSize);FileStream.Position := 0;TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Up.LoadFromStream(FileStream);end;if (g_GameLoginConfig.ComponentImages[I].HotSize > 0) and (TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Hot <> nil) then beginFileStream.Clear;FileStream.Write(Buffer^, g_GameLoginConfig.ComponentImages[I].HotSize);Buffer := IncPointer(Buffer, g_GameLoginConfig.ComponentImages[I].HotSize);FileStream.Position := 0;TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Hot.LoadFromStream(FileStream);end;if (g_GameLoginConfig.ComponentImages[I].DownSize > 0) and (TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Down <> nil) then beginFileStream.Clear;FileStream.Write(Buffer^, g_GameLoginConfig.ComponentImages[I].DownSize);Buffer := IncPointer(Buffer, g_GameLoginConfig.ComponentImages[I].DownSize);FileStream.Position := 0;TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Down.LoadFromStream(FileStream);end;if (g_GameLoginConfig.ComponentImages[I].Disabled > 0) and (TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Disabled <> nil) then beginFileStream.Clear;FileStream.Write(Buffer^, g_GameLoginConfig.ComponentImages[I].Disabled);Buffer := IncPointer(Buffer, g_GameLoginConfig.ComponentImages[I].Disabled);FileStream.Position := 0;TRzBmpButton(g_ComponentList.Items[I - 1]).Bitmaps.Disabled.LoadFromStream(FileStream);end;end;end;FreeMem(g_Buffer);FileStream.Free;//设置列表TreeView.Color := g_GameLoginConfig.ViewBColor;TreeView.Font.Color := g_GameLoginConfig.ViewFColor;g_boReadSkin := True;
end;procedure TfrmMain.TimerReakSkinTimer(Sender: TObject);
beginTimerReakSkin.Enabled := False;ReadSkin;
end;initializationbeging_ComponentList := TList.Create;end;
finalizationbeging_ComponentList.Free;end;
end.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_398876.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不会 Vue,但不影响我学 diff 算法

前言 现在社会各行各业大都面临着寒冬&#xff0c;互联网行业最近还出现了裁员潮&#xff0c;导致前端是越来越卷&#xff0c;普通学校的应届生不仅要跟985、211毕业的学生以及研究生进行竞争&#xff0c;甚至还需要和最近刚被裁的、有了几年工作经验的程序员竞争&#xff0c;…

page.json

uni-app需要给page.json文件需要进行配置路由,否则会不报错,也跳转不过去

【数模/启发式算法】蚁群算法

文章目录简介符号说明核心思想流程图文章使用到的测试函数基本步骤蚁群算法代码简介 蚁群算法是一种用来寻找优化路径的概率型算法。它由Marco Dorigo于1992年在他的博士论文中提出&#xff0c;其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。 这种算法具有分布计算、信息正…

Arduino播放声音

玩软件有点虚无&#xff0c;没有实际东西&#xff0c;所以接下来要体验下硬件与软件结合。 1 Arduino Arduino是一种包含硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;的开源电子平台。硬件部分是可以用来做电路连接的Arduino电…

小白学习Java第四十三天

Git概述 &#xff08;一&#xff09;什么是Git Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理&#xff0c;是软件配置管理的核心思想之一…

设计模式学习笔记(五) - 观察者模式 Observer

目录 观察者模式 Observer 一、背景描述 Version 1 (面向过程) Version 2 (面向对象) Version 3 (单个观察者) Version 4 (多个观察者) Version 5 (分离观察者与被观察者) 二、不同事件下的观察者模式 三、事件本身也可以形成继承体系 四、观察者常用场景 观察者模式…

Selenium基础 — 鼠标操作

1、鼠标事件介绍 前面例子中我们已经学习到可以用click()来模拟鼠标的单击操作&#xff0c;而我们在实际的web产品测试中发现&#xff0c;有关鼠标的操作&#xff0c;不单单只有单击&#xff0c;有时候还要用到右击&#xff0c;双击&#xff0c;拖动等操作&#xff0c;这些操作…

【Nginx】认识与基本使用 Nginx 实现反向代理、配置负载均衡

文章目录1. Nginx 概述1.1 Nginx 介绍1.2 Nginx 下载和安装1.3 Nginx 目录结构2. Nginx 命令3. Nginx 配置文件结构4. Nginx 具体应用4.1 部署静态资源4.2 反向代理4.2.1 介绍4.2.2 配置反向代理4.3 负载均衡4.3.1 介绍4.3.2 配置负载均衡4.3.3 负载均衡策略1. Nginx 概述 1.1…

Ubuntu开机界面出现“error found when loading /root/.profile”

原因 今天一开始按照一篇文章&#xff0c;想把普通用户的权限提高到最高权限&#xff0c;修改了**/etc/passwd**文件&#xff0c;然后重启&#xff0c;发现之前的用户进不去了&#xff0c;一开机就出现如下信息 解决方法 1、重启虚拟机进入recovery模式&#xff08;长按shi…

计算机网络-第一章 | 王道考研

目录 一、基本介绍 定义 功能 组成 分类 标准化工作 标准的分类 标准化工作相关组织 二、性能指标 ※ 速率 带宽 ※吞吐量 时延 时延带宽积 往返时延RTT 利用率 三、分层结构 ※ 分层基本规则 正式认识分层 7层OSI参考模型 怎么来的 怎么分的 怎么传的…

<特殊类设计与单例模式>——《C++高阶》

目录 1.请设计一个类&#xff0c;不能被拷贝 2. 请设计一个类&#xff0c;只能在堆上创建对象 3. 请设计一个类&#xff0c;只能在栈上创建对象 4. 请设计一个类&#xff0c;不能被继承 5. 请设计一个类&#xff0c;只能创建一个对象(单例模式) 后记&#xff1a;●由于…

GD32F307VC+WIN10+VSCODE+GCC+JLINK环境build

为了构建Cortex M系列单片机免费开源的开发环境&#xff0c;网络上了解来看VSCODEGCCJLINK是一套比较高效的组合方式&#xff0c;下面记录环境搭建的流程。 我这边的PC环境为 WIN10专业版64bit。 工具准备 1. arm-none-eabi-gcc下载及安装 官网下载链接&#xff1a;Downloa…

c++数据结构:数组和向量

线性表&#xff1a; 在数据元素的非空有限集中 存在唯一的一个被叫做“第一个”的数据元素存在唯一的一个被叫做“最后一个”的数据元素除第一个之外&#xff0c;集合中的每个数据元素均只有一个前驱除最后一个之外&#xff0c;每个集合元素均只有一个后继数据结构中线性结构指…

文字识别检测入门(1)

CTPN 优点&#xff1a;对水平文字检测效果超级好 缺点&#xff1a;对扭曲的文字不好 RRPN 在faster的基础上改进 RPN改为RRPN ROI pooling改进为RROI pooling 能解决旋转&#xff0c;但是解决不了弯曲的曲面问题 EAST Anchor free 特征合并&#xff0c;检测不同尺度文本 检测各…

刷爆leetcode第三期 0007~0010

刷爆leetcode第三期 0007~0010 题目一 反转链表解法一解法二题目二 链表的中间节点题目三 链表的倒数第K个节点题目四 合并两个有序链表题目一 反转链表 解法一 给定单链表的头节点 head &#xff0c;请反转链表&#xff0c;并返回反转后的链表的头节点。 示例 1&#xff1a…

python与人工智能:线性回归和逻辑回归

线性回归 线性回归是利用数理统计中回归分析&#xff0c;来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法&#xff0c;运用 十分广泛。梯度下降&#xff1f; 梯度下降法的基本思想可以类比为一个下山的过程。 假设这样一个场景&#xff1a;一个人被困在山上&a…

零拷贝总结

数据交互模式 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dqLJVb5U-1665401648551)(en-resource://database/1074:1)] 读数据过程&#xff1a; 应用程序要读取磁盘数据&#xff0c;调用 read()函数从而实现用户态切换内核态&#xff0c;这是第 …

论文/机器学习笔记:SENet (Squeeze-and-Excitation Networks)

Image 2017 挑战赛夺冠paper 1 motivation 希望显式地建模特征通道&#xff08;channel&#xff09;之间的相互依赖关系 通过学习的方式来自动获取到每个特征通道的重要程度依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征 2 模型 给定一个输入 x&#xff…

利用phpstudy导入mysql文件

1.创建mysql文件 mysql 常用命令&#xff1a; 打开mysql: mysql -u root -p 查看数据库&#xff1a; show databases; 创建 数据库: create database baseName (数据库名称) 使用数据库&#xff1a; use baseName(数据库名称) 显示表&#xff1a;show tables; 创建表&#xff…

C#【高级篇】 IntPtr是什么?怎么用?

C#学习汇总 - 总目录 C#【高级篇】 IntPtr是什么&#xff1f;怎么用&#xff1f;前言一、IntPtr&#xff08;IntPointer&#xff09;的由来二、IntPtr&#xff08;属于结构体&#xff09;的说明三、IntPtr的使用示例1、int类型与IntPtr类型之间的转换2、string类型与IntPtr之间…