Player information JSON
Savi0ur opened this issue · 16 comments
In player information JSON all maps represent as new JSON object. When new map releases, code wich parsing this json cant know in advance a new map name, to create new object for this map. So always on new map releases you need to handle new map object. I think maps should be represented as JSON array, not infinity JSON objects.
Current json part:
{
"types": {
"Novice": {
"maps": {
"Give u the Moon": {
"points": 3,
"total_finishes": 27013,
"finishes": 0
},
"Tutorial": {
"points": 1,
"total_finishes": 198040,
"finishes": 2,
"rank": 90420,
"time": 445.24,
"first_finish": 1645978251
},
"SeMang 2": {
"points": 5,
"total_finishes": 31703,
"finishes": 1,
"rank": 587,
"time": 368.14,
"first_finish": 1645022988
}
}
}
}
}
My suggestion:
{
"types": {
"Novice": {
"maps": [
{
"map_name": "Give u the Moon",
"points": 3,
"total_finishes": 27013,
"finishes": 0
},
{
"map_name": "Tutorial",
"points": 1,
"total_finishes": 198040,
"finishes": 2,
"rank": 90420,
"time": 445.24,
"first_finish": 1645978251
},
{
"map_name": "SeMang 2",
"points": 5,
"total_finishes": 31703,
"finishes": 1,
"rank": 587,
"time": 368.14,
"first_finish": 1645022988
}
]
}
}
}
You can iterate over an object in JavaScript, no need to adjust how it's represented.
I think we structured it like this because we wanted O(1) lookup on the client and a dictionary gets directly parsed to a hash table.
You can iterate over an object in JavaScript, no need to adjust how it's represented.
I want to work with this json data in my own code, not on JavaScript. Now i need to create 1854 classes for all maps on ddnet, and a new one on each map releases, or do special data parsing logic. Looks weird
What language are you making your project in? Most do provide easy iteration of hashmaps, or the json library itself provides iteration through json dictionaries.
If neither is helpful you could just transform the data at the entrypoint into the form you want.
This change would mean we have to do the exact same transformation I suggest in our client, so easier for you is harder for us, a zero sum change if you will :)
My project on Kotlin. I use kotlin serialization to parse json
Hm, I'm not familiar with Kotlin, but are you sure you can't get it to deserialize into a Map<String, TwMap>
for some generic TwMap
class? I don't quite see why you are forced to create a class for each map.
At the very least, I'm pretty certain it's possible in Java with GSON
Thanks for the advice! I'll try
Hm, I'm not familiar with Kotlin, but are you sure you can't get it to deserialize into a
Map<String, TwMap>
for some genericTwMap
class? I don't quite see why you are forced to create a class for each map.At the very least, I'm pretty certain it's possible in Java with GSON
Thanks, it really helped me!
But i have next question. In "types", field "rank" is integer when you have rank points, and string when you doesnt. Isnt it an issue?
string:
"DDmaX.Easy": {
"points": {
"total": 144,
"points": 128,
"rank": 1705
},
"team_rank": {
"rank": "unranked"
},
"rank": {
"rank": "unranked"
}
integer:
"DDmaX.Next": {
"points": {
"total": 1912,
"points": 1216,
"rank": 1500
},
"team_rank": {
"points": 53,
"rank": 132
},
"rank": {
"points": 34,
"rank": 109
}
"points": 34,
"rank": 109
}
This player info has nothing to do with client. I'm assuming it's about https://ddnet.org/players/?json2=deen
I didn't want to just put a number for "rank", because 0 would be wrong. So you have to consciously handle if it's a string ("unranked") or a number.
This kind of model doesn't fit well with a strongly typed language's automatic deserialization though.
Hm, maybe -1 could be used as unranked? It might be less annoying for json libraries for statically typed languages.
Ok, will change it. Edit: Done
Or null.
Null would also be another type, and have to be handled I guess.
At least in Rust, you can deserialize something that is sometimes and integer and sometimes null as Option<i64>
. I'd assume other languages have similar things. Quick checking shows that this is also available for @Savi0ur's Kotlin library: https://github.com/Kotlin/kotlinx.serialization/blob/dc950f5098162a3f8dd742d04b95f9a0405470e1/docs/basic-serialization.md#nullable-properties.
At least in Rust, you can deserialize something that is sometimes and integer and sometimes null as
Option<i64>
. I'd assume other languages have similar things. Quick checking shows that this is also available for @Savi0ur's Kotlin library: https://github.com/Kotlin/kotlinx.serialization/blob/dc950f5098162a3f8dd742d04b95f9a0405470e1/docs/basic-serialization.md#nullable-properties.
Yes, with null it will work. But not with "unranked"
Great, that's cleaner, changed it to null.