1 module pubg.match; 2 3 import std.stdio:writeln; 4 import std.file: write; 5 import pubg.request; 6 import std.json; 7 import std.conv: parse; 8 9 class MatchAttributes 10 { 11 public: 12 this(JSONValue json) 13 { 14 this.json = json; 15 } 16 string getCreationDate() 17 { 18 return this.json["createdAt"].str; 19 } 20 int getDuration() 21 { 22 return cast(int)this.json["duration"].integer; 23 } 24 string getGameMode() 25 { 26 return this.json["gameMode"].str; 27 } 28 string getMapName() 29 { 30 return this.json["mapName"].str; 31 } 32 string getShardId() 33 { 34 return this.json["shardId"].str; 35 } 36 string getTitleId() 37 { 38 return this.json["titleId"].str; 39 } 40 private: 41 JSONValue json; 42 } 43 44 class MatchAssets 45 { 46 public: 47 this(JSONValue json) 48 { 49 this.json = json; 50 } 51 string getId() 52 { 53 return this.json["data"].array[0]["id"].str; 54 } 55 private: 56 JSONValue json; 57 } 58 59 class MatchRosters 60 { 61 public: 62 this(JSONValue json) 63 { 64 this.json = json; 65 } 66 string[] getRosterIds() 67 { 68 auto data = this.json["data"].array; 69 string[] ret; 70 foreach (j; data) 71 { 72 if (j["type"].str == "roster") 73 ret ~= j["id"].str; 74 } 75 return ret; 76 } 77 private: 78 JSONValue json; 79 } 80 81 class MatchRelationships 82 { 83 public: 84 this(JSONValue json) 85 { 86 this.json = json; 87 } 88 MatchAssets getAssets() 89 { 90 return new MatchAssets(this.json["assets"]); 91 } 92 MatchRosters getRosters() 93 { 94 return new MatchRosters(this.json["rosters"]); 95 } 96 private: 97 JSONValue json; 98 } 99 100 class MatchLinks 101 { 102 public: 103 this(JSONValue json) 104 { 105 this.json = json; 106 } 107 string getSchema() 108 { 109 return this.json["schema"].str; 110 } 111 string getSelf() 112 { 113 return this.json["self"].str; 114 } 115 private: 116 JSONValue json; 117 } 118 119 class MatchData 120 { 121 public: 122 this(JSONValue json) 123 { 124 this.json = json; 125 } 126 MatchAttributes getAttributes() 127 { 128 return new MatchAttributes(this.json["attributes"]); 129 } 130 MatchRelationships getRelationships() 131 { 132 return new MatchRelationships(this.json["relationships"]); 133 } 134 string getType() 135 { 136 return this.json["type"].str; 137 } 138 string getId() 139 { 140 return this.json["id"].str; 141 } 142 private: 143 JSONValue json; 144 } 145 146 class MatchParticipant 147 { 148 public: 149 this(JSONValue json) 150 { 151 this.json = json; 152 } 153 string getActor() 154 { 155 return this.json["actor"].str; 156 } 157 string getShardId() 158 { 159 return this.json["shardId"].str; 160 } 161 int getDBNOs() 162 { 163 return cast(int)this.json["attributes"]["stats"]["DBNOs"].integer; 164 } 165 int getAssists() 166 { 167 return cast(int)this.json["attributes"]["stats"]["assists"].integer; 168 } 169 int getBoosts() 170 { 171 return cast(int)this.json["attributes"]["stats"]["boosts"].integer; 172 } 173 int getDamageDealt() 174 { 175 return cast(int)this.json["attributes"]["stats"]["damageDealt"].integer; 176 } 177 string getDeathType() 178 { 179 return this.json["attributes"]["stats"]["deathType"].str; 180 } 181 int getHeadshotKills() 182 { 183 return cast(int)this.json["attributes"]["stats"]["headShotKills"].integer; 184 } 185 int getHeals() 186 { 187 return cast(int)this.json["attributes"]["stats"]["heals"].integer; 188 } 189 int getKillPlace() 190 { 191 return cast(int)this.json["attributes"]["stats"]["killPlace"].integer; 192 } 193 int getKillPoints() 194 { 195 return cast(int)this.json["attributes"]["stats"]["killPoints"].integer; 196 } 197 float getKillPointsDelta() 198 { 199 return cast(float)this.json["attributes"]["stats"]["killPointsDelta"].floating; 200 } 201 int getKillStreaks() 202 { 203 return cast(int)this.json["attributes"]["stats"]["killPoints"].integer; 204 } 205 int getKills() 206 { 207 return cast(int)this.json["attributes"]["stats"]["kills"].integer; 208 } 209 int getLastKillPoints() 210 { 211 return cast(int)this.json["attributes"]["stats"]["lastKillPoints"].integer; 212 } 213 int getLastWinPoints() 214 { 215 return cast(int)this.json["attributes"]["stats"]["lastWinPoints"].integer; 216 } 217 int getLongestKill() 218 { 219 return cast(int)this.json["attributes"]["stats"]["longestKill"].integer; 220 } 221 int getMostDamage() 222 { 223 return cast(int)this.json["attributes"]["stats"]["longestKill"].integer; 224 } 225 string getName() 226 { 227 return this.json["attributes"]["stats"]["name"].str; 228 } 229 string getPlayerId() 230 { 231 return this.json["attributes"]["stats"]["playerId"].str; 232 } 233 int getRevives() 234 { 235 return cast(int)this.json["attributes"]["stats"]["revives"].integer; 236 } 237 int getRideDistance() 238 { 239 return cast(int)this.json["attributes"]["stats"]["rideDistance"].integer; 240 } 241 int getRoadKills() 242 { 243 return cast(int)this.json["attributes"]["stats"]["roadKills"].integer; 244 } 245 int getTeamKills() 246 { 247 return cast(int)this.json["attributes"]["stats"]["teamKills"].integer; 248 } 249 int getTimeSurvived() 250 { 251 return cast(int)this.json["attributes"]["stats"]["timeSurvived"].integer; 252 } 253 int getVehicleDestroys() 254 { 255 return cast(int)this.json["attributes"]["stats"]["vehicleDestroys"].integer; 256 } 257 float getWalkDistance() 258 { 259 return cast(float)this.json["attributes"]["stats"]["walkDistance"].floating; 260 } 261 int getWeaponsAcquired() 262 { 263 return cast(int)this.json["attributes"]["stats"]["weaponsAcquired"].integer; 264 } 265 int getWinPlace() 266 { 267 return cast(int)this.json["attributes"]["stats"]["winPlace"].integer; 268 } 269 int getWinPoints() 270 { 271 return cast(int)this.json["attributes"]["stats"]["winPoints"].integer; 272 } 273 float getWinPointsDelta() 274 { 275 return cast(float)this.json["attributes"]["stats"]["winPointsDelta"].floating; 276 } 277 override int opCmp(Object other) 278 { 279 if (other is null || this is null) 280 return 0; 281 if (this.getKills() == (cast(MatchParticipant)other).getKills()) 282 return 0; 283 return this.getKills() -(cast(MatchParticipant)other).getKills(); 284 } 285 private: 286 JSONValue json; 287 } 288 289 class MatchRoster 290 { 291 public: 292 this(JSONValue json) 293 { 294 this.json = json; 295 } 296 string getShardId() 297 { 298 return this.json["attributes"]["shardId"].str; 299 } 300 int getRank() 301 { 302 return cast(int)this.json["attributes"]["stats"]["rank"].integer; 303 } 304 int getTeamId() 305 { 306 return cast(int)this.json["attributes"]["stats"]["teamId"].integer; 307 } 308 string getId() 309 { 310 return this.json["id"].str; 311 } 312 bool getWon() 313 { 314 auto s = this.json["attributes"]["won"].str; 315 return parse!bool(s); 316 } 317 string[] getParticipantIds() 318 { 319 string[] ret; 320 foreach (j; this.json["relationships"]["participants"]["data"].array) 321 { 322 if (j["type"].str == "participant") 323 ret ~= j["id"].str; 324 } 325 return ret; 326 } 327 private: 328 JSONValue json; 329 } 330 331 class MatchIncluded 332 { 333 public: 334 this(JSONValue json) 335 { 336 this.json = json; 337 } 338 MatchParticipant[] getParticipants() 339 { 340 MatchParticipant[] stats; 341 auto data = this.json.array; 342 foreach(j; data) 343 { 344 if (j["type"].str == "participant") 345 { 346 stats ~= new MatchParticipant(j); 347 } 348 } 349 return stats; 350 } 351 MatchRoster[] getRosters() 352 { 353 MatchRoster[] rosters; 354 auto data = this.json.array; 355 foreach(j; data) 356 { 357 if (j["type"].str == "roster") 358 { 359 rosters ~= new MatchRoster(j); 360 } 361 } 362 return rosters; 363 } 364 private: 365 JSONValue json; 366 } 367 368 class Match 369 { 370 public: 371 this(char[] content) 372 { 373 this.json = parseJSON(cast(string)content); 374 //auto data = this.json["included"]; 375 //writeln(this.json.toPrettyString()); 376 //write("test.json", this.json.toPrettyString()); 377 } 378 this(JSONValue json) 379 { 380 this.json = json; 381 } 382 MatchData getData() 383 { 384 return new MatchData(this.json["data"]); 385 } 386 MatchIncluded getIncluded() 387 { 388 return new MatchIncluded(this.json["included"]); 389 } 390 private: 391 JSONValue json; 392 } 393 394 class MatchRequest : ObjectRequest 395 { 396 public: 397 this(string region) 398 { 399 super("https://api.playbattlegrounds.com/shards/" ~ region ~ "/"); 400 } 401 Match getMatch(string matchID) 402 { 403 return new Match(this.request("matches/" ~ matchID)); 404 } 405 }