Closed AdriaanBoshoff closed 6 years ago
I have tried to replicate your error without any success. Does the attached json fail? If not please send what fails. Also please attach where in the code the exception occurs and a stacktrace if available.
It should not be the size of the string. That's way too little text to even consider it a problem.
Hi, sorry for this late reply. I had some personal stuff to deal with. I think it might be the way I'm parsing it. The actual raw json I receive is the following:
{
"Message": "[\r\n {\r\n \"SteamID\": \"removed\",\r\n \"OwnerSteamID\": \"0\",\r\n \"DisplayName\": \"remove\",\r\n \"Ping\": 48,\r\n \"Address\": \"remove\",\r\n \"ConnectedSeconds\": 5137,\r\n \"VoiationLevel\": 0.0,\r\n \"CurrentLevel\": 0.0,\r\n \"UnspentXp\": 0.0,\r\n \"Health\": 100.0\r\n },\r\n {\r\n \"SteamID\": \"remove\",\r\n \"OwnerSteamID\": \"0\",\r\n \"DisplayName\": \"removed\",\r\n \"Ping\": 51,\r\n \"Address\": \"removed\",\r\n \"ConnectedSeconds\": 2158,\r\n \"VoiationLevel\": 0.0,\r\n \"CurrentLevel\": 0.0,\r\n \"UnspentXp\": 0.0,\r\n \"Health\": 95.87633\r\n }\r\n]",
"Identifier": 0,
"Type": "Generic",
"Stacktrace": ""
}
So what I do is I parse it and then parse the "Message" giving me the following:
[
{
"SteamID": "removed",
"OwnerSteamID": "0",
"DisplayName": "removed",
"Ping": 200,
"Address": "removed",
"ConnectedSeconds": 6386,
"VoiationLevel": 0.0,
"CurrentLevel": 0.0,
"UnspentXp": 0.0,
"Health": 97.70907
},
{
"SteamID": "removed",
"OwnerSteamID": "0",
"DisplayName": "removed",
"Ping": 264,
"Address": "removed",
"ConnectedSeconds": 3882,
"VoiationLevel": 0.0,
"CurrentLevel": 0.0,
"UnspentXp": 0.0,
"Health": 100.0
}
]
How would you recommend I parse the raw data I receive from the server so that I can get a proper player list.
procedure Tfrmmain.websocketclientWebRconDataIn(Sender: TObject; DataFormat: Integer; Text: string; EOM: Boolean);
begin
LogWebRcon(ParseWebRconIncomingData(Text));
end;
function Tfrmmain.ParseWebRconIncomingData(Data: string): string;
var
Text: TJSON;
chat2: TJSON;
chat: string;
begin
Text := TJSON.Parse(Data);
try
if (Text['Type'].AsString = 'Generic') or (Text['Type'].AsString = 'Error') or (Text['Type'].AsString = 'Warning') then
begin
if Text['Identifier'].AsInteger = 10 then //This will run if the Identidier is 10 because this means the playerlist has been requested
begin
GetPlayers(Text['Message'].AsString);
end
else
Result := Text['Message'].AsString;
Text.Free;
end
else if Text['Type'].AsString = 'Chat' then
begin
chat := Text['Message'].AsString;
chat2 := TJSON.Parse(chat);
Result := chat2['Username'].AsString + ': ' + chat2['Message'].AsString;
chat2.Free;
end;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
procedure Tfrmmain.GetPlayers(Data: string);
var
users, user: TJSON;
item: TListItem;
begin
users := TJSON.Parse(Data);
try
try
for user in users do
begin
item := listViewPlayers.Items.Add;
item.Caption := user['SteamID'].AsString;
item.SubItems.Add(user['ConnectedSeconds'].AsString + ' Seconds');
item.SubItems.Add(user['DisplayName'].AsString);
item.SubItems.Add(user['Ping'].AsString);
item.SubItems.Add(user['Address'].AsString);
item.SubItems.Add(user['Health'].AsString);
end;
finally
users.Free;
end;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
procedure Tfrmmain.LogWebRcon(Text: string);
begin
mmoWebRconLog.Lines.Add('[' + DateTimeToStr(now) + '] ' + Text);
end;
I understand this code is really messy but this was the only way I could get it working. BTW there is no break or anything. My program just crashes even if I run it in debug mode.
So I've recreated the code so that everything happens in one function except for the logging part.
function Tfrmmain.ParseWebRconIncomingData(Data: string): string;
var
Text: TJSON;
chat: TJSON;
users, user: TJSON;
item: TListItem;
begin
Text := TJSON.Parse(Data);
if Text['Identifier'].AsInteger = 1 then
begin
//GetPlayers(Text['Message'].AsString);
users := TJSON.Parse(Text['Message'].AsString);
for user in users do
begin
try
item := listViewPlayers.Items.Add;
item.Caption := user['SteamID'].AsString;
item.SubItems.Add(user['ConnectedSeconds'].AsString + ' Seconds');
item.SubItems.Add(user['DisplayName'].AsString);
item.SubItems.Add(user['Ping'].AsString);
item.SubItems.Add(user['Address'].AsString);
item.SubItems.Add(user['Health'].AsString);
except
on E: Exception do
ShowMessage(e.Message);
end;
end;
Result := '';
Exit;
end
else if (Text['Type'].AsString = 'Generic') or (Text['Type'].AsString = 'Error') or (Text['Type'].AsString = 'Warning') then
begin
Result := Text['Message'].AsString;
Exit;
end
else if Text['Type'].AsString = 'Chat' then
begin
chat := TJSON.Parse(Text['Message'].AsString);
Result := chat['Message'].AsString;
end;
end;
Here is a msg fromt he debugger: https://i.imgur.com/KlkhpyZ.png and https://i.imgur.com/A7OXZHV.png
It seems to only happen after it runs this: item.SubItems.Add(user['Health'].AsString);
So this is interesting. Your code works on my machine. Have you checked that you run the latest version of djson.pas?
I would recommend that you install madexcept. It'll give you a usable stacktrace, making it easier to debug these access violations.
Thanks will do. I have a really big project that i started back in mod 2017. Started with rad studio 10.1.1 and now the latest. I've had a huge amount of issues lately. I'm thinking of just starting the project over amd copy / pasting the code.
So it seems when I try to parse this it works fine but as soon as there are 3 players it just gives me an access violation. Any reason why?
My parse code:
EDIT: Is it possible that the string that it tries to parse is to long?