Cześć.
Bawię się po raz pierwszy w życiu Kaillerą jako lame developer - koder, a nie gracz. I mam problem. Jak wynika z dokumentacji exportowana funkcja kailleraclient.dll'
o nazwie _kailleraSetInfos@4
, przyjmuje jako parametr pewną strukturę. W pliku nagłowkowym w C++ wygooglowanym na sieci widzimy:
//...
typedef struct {
char *appName;
char *gameList;
int (WINAPI *gameCallback)(char *game, int player, int numplayers);
void (WINAPI *chatReceivedCallback)(char *nick, char *text);
void (WINAPI *clientDroppedCallback)(char *nick, int playernb);
void (WINAPI *moreInfosCallback)(char *gamename);
} kailleraInfos;
//...
/*
kailleraSetInfos:
Use this method for setting up various infos:
Required:
- appName must be 128 chars max.
- gameList is composed of all the game names separated by a NULL char (\0).
The list ends with 2 NULL chars (\0\0).
Be sure to only put available games there.
- gameCallback will be the function called when a new game starts
game -> name of the selected game
player -> player number (1-8). 0 for spectator.
numplayers -> number of players in the game (1-8)
Optional:
- chatReceivedCallback will be the function called when a chat line text
has been received. Set it to NULL if you don't need/want this callback.
- clientDroppedCallback will be the function called when a client drops
from the current game. Set it to NULL if you don't need/want this callback.
- moreInfosCallback will be the function called when the user selects
"More infos about this game..." in the game list context menu.
Set it to NULL if you don't need/want this feature.
*/
void (__stdcall* kailleraSetInfos) (kailleraInfos *infos);
W Delphi w mojej dllce wygląda to tak:
type
type
TkailleraInfos = packed record
appName : PChar;
gameList : PChar;
gameCallback : function(game : PChar; player : integer; numplayers : integer) : integer; stdcall;
chatReceivedCallback : procedure(Nick : PChar; text : PChar); stdcall;
clientDroppedCallback : procedure(nick : PChar; playernb : integer); stdcall;
moreInfosCallback : procedure(gamename : PChar); stdcall;
end;
I teraz mam hookniętą lokalnie funkcje w takiej postaci:
procedure Hooked_kailleraSetInfos(var Infos : TkailleraInfos); stdcall;
type
TOriginal_kailleraSetInfos = procedure(var Infos : TkailleraInfos); stdcall;
var
S : string;
begin
Hook[2].UnHook;
S := PChar(Infos.gameList);
SaveTextToFile(Test_Path + 'gejmlist.aaa', S);
TOriginal_kailleraSetInfos(Hook[2].BaseAddr)(Infos);
Hook[2].Hook;
end;
I w pliku winikowym mam zawsze pierwszą pozycję z listy. Nie pomogło:
SetString(S, PChar(@Infos.gameList), 100);
Nie pomogły różne lcpystr i takie tam. Chyba, że źle ich użyłem. I tutaj pytanie. Nie mając żadnej zmiennej zawierającej wielkość tej listy, a chce od Emulatora MAME otrzymać ich kompletną listę w postaci stringa - nawet z tymi bajtami null. Ustawianie większego rozmiaru przez SetLength też nie pomogło.
Wiem, że lame pytanie, ale tutaj nie wiem jak to ogarnąc. Gdy robiłem, tak jak powyżej z SetString
, w pliku otrzymałem jakieś "śmieci". A kiedy samodzielnie zrobię:
Infos.gameList := 'jeden' + #0 + 'dwa' + #0#0;
To jest ok, ale ja chcę mieć całą listę przekazywaną przez emulator. A nie tylko pierwszą jej pozycję. Z góry dziękuję za wszelkie przykłady kodów w Delphi.