|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
mIRC has a line limit of ~4000 characters and the responses are often too long to fit. The easiest way to get the full information is just to open the relevant URL in your web browser, then you can examine the JSON structure. Look at the user commands I've added to the script, you can see how I access specific data: var %matches = $CoD.Matches($1,$2,$3,$4)
var %match = $json(%matches,data,matches,0)
var %kills = $json(%match,playerStats,kills).value
or
var %kills = $json(%matches,data,matches,0,playerStats,kills).value I've made some more changes to CallOfDuty.mrc and changed the $CoD.Call alias so that it opens the URL when debugging is enabled.
Last edited by Loki12583; 21/10/20 07:02 PM.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
v7.53 increased the line length to 8kb, and 7.62 increased it again to 10kb. But there's always a website out there who can create longer string lengths between carriage returns.
I'm not sure how these lengths apply to extending the max for things like /sockread, so you'd have to test. As applied to %string the line length generally means 'characters' but to &binvar it often means 'bytes'. As long as the website has normal text there won't be a difference. But if there are characters above $chr(127) your &binvar can sometimes be unexpectedly shortchanged.
//var %string $str($chr(10004),6000) | bset -t &var 1 %string | echo -a $len($bvar(&var,1-).text) = 1/3rd *$maxlenl vs $len(%string)
You can now see the line length limit with $maxlenl, but you can't easily use lengths near that amount since that's the limit for the entire line, including commands, other parameters, and the %variable name itself.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Awesome that you keep adding stuff to this one. I figured out how to get the data from the JSON like $json(%stats,data,lifetime,all,properties,br,properties,wins).value but it takes the first value it hits, but i want to take the Br wins for example. looks like this "br":{"properties":{"wins":76.0 tried alot of different stuff to get down to that one but i have failed.
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
Do you have an example of the full plain-text JSON data? Use pastebin.com or similar to post it, if it can't be accessed from a browser.
Once we have an example of the data, could you tell us each piece of data you want to extract from it
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Last edited by Bast; 22/10/20 04:24 AM.
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
Here's a handy site that makes viewing the JSON data far easier: jsonviewer. Paste the JSON text in then click the "Viewer" button at the very top Now lets say you want to access various items in the br mode's data, all you have to do is make a call to $json for each piece of data you want to retrieve: alias example {
;; ... code that retrieves the json and parses it
;; assume the JSON handler's name is stored in %stats
;; echos: BR Wins: 76
echo -ag BR Wins: $json(%stats, data, lifetime, mode, br, properties, wins).value
;; echos: BR Kills: 10843
echo -ag BR Kills: $json(%stats, data, lifetime, mode, br, properties, kills).value
;; Or if you want both on the same line
;; echos: BR Wins: 76 - BR Kills: 10843
echo -ag BR Wins: $json(%stats, data, lifetime, mode, br, properties, wins).value - BR Kills: $json(%stats, data, lifetime, mode, br, properties, kills).value
}
Last edited by FroggieDaFrog; 22/10/20 04:44 AM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
right now i got it when i see it in the format. ![whistle whistle](/images/graemlins/mirc/whistle.gif) You are an awesome person who has helped alot, dont know how you coop with us noobs. ![grin grin](/images/graemlins/mirc/grin.gif) so now i just need to add some commands to my twitch, but i think i will be abel to do that myself. so again. Thank You very much
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
dont know how you coop with us noobs. We were all a newbie at one point. I'm sure we've given plenty of people headaches when we first started, so its only fair we take our share of em now.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
im making so all values is saved to an ini file. looks like this ;;-------------------;;
;; CrossBow ;;
;;-------------------;;
var %weaponname CrossBow | var %weaponapiname iw8_sn_crossbow
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Hits $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,hits).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Kills $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kills).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname KD $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kdRatio).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname HeadShots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,headshots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Accuracy $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,accuracy).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Shots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,shots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Deaths $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,deaths).value
;;-------------------;;
;; Kar98k ;;
;;-------------------;;
var %weaponname Kar98k | var %weaponapiname iw8_sn_kilo98
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Hits $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,hits).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Kills $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kills).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname KD $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kdRatio).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname HeadShots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,headshots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Accuracy $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,accuracy).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Shots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,shots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Deaths $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,deaths).value
;;-------------------;;
;; EBR-14 ;;
;;-------------------;;
var %weaponname EBR-14 | var %weaponapiname iw8_sn_mike14
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Hits $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,hits).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Kills $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kills).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname KD $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kdRatio).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname HeadShots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,headshots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Accuracy $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,accuracy).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Shots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,shots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Deaths $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,deaths).value but can i make a loop,instead of typing like 1000 rows of almost the same thing? to something like ;;-------------------;;
;; CrossBow ;;
;;-------------------;;
var %weaponname CrossBow | var %weaponapiname iw8_sn_crossbow
;;-------------------;;
;; Kar98k ;;
;;-------------------;;
var %weaponname Kar98k | var %weaponapiname iw8_sn_kilo98
;;-------------------;;
;; EBR-14 ;;
;;-------------------;;
var %weaponname EBR-14 | var %weaponapiname iw8_sn_mike14
;Write stuff to ini
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Hits $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,hits).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Kills $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kills).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname KD $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,kdRatio).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname HeadShots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,headshots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Accuracy $round($json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,accuracy).value,2)
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Shots $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,shots).value
writeini $shortfn($mircdirscripts) $+ %statsfiles $+ Stats.ini %weaponname Deaths $json(%stats, data, lifetime, itemData, weapon_marksman, %weaponapiname $+ ,properties,deaths).value
Last edited by Bast; 22/10/20 06:06 PM.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
You can have an alias which does the writing to the .ini, and you can pass "CrossBow" as the $1 parm, and "iw8_sn_crossbow" as the $2. If you have a place where all the weapons are stored, you can loop through that list to fetch the pair of parameters to be passed to the alias. If the list of weapons is short enough to fit in 1 big long line, you could loop through that until the list is empty, passing 1 pair at a time.
tokenize 32 weapon1 weapon1api weapon2 weapon1api etc
while ($1 != $null) {
aliasname_that_does_the_ini_write $1 $2 %stats %statsfiles
tokenize 32 $3-
} note there's a -n switch for writeini related to .ini files larger than 64k, and it looks like you're writing a lot of data to it.
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
There is looping built into jsonformirc. You might consider adding these items to hash tables before writing to ini, I don't know if mIRC will keep the file handle open between all the operations and so many writeinis could take much longer. It takes 10 seconds just to loop and assign variables. This will loop over every property of every weapon: alias weapons.store {
var %stats = $$CoD.Stats($1,$2,$3,$4)
if (!$hget(cod.weapons)) { weapons.init }
var %file = $shortfn($mircdirscripts\stats\UserStats.ini)
var %ref = $json(%stats,data,lifetime,itemData)
noop $JSONForEach(%ref,weapons.foreach %file).walk
}
alias weapons.foreach {
var %target = $1, %ref = $2
var %path = $json(%ref).pathLength
var %weaponapi = $jsonpath(%ref,$calc(%path - 2))
var %weapon = $weapons.enum(%weaponapi)
var %prop = $jsonpath(%ref,%path)
var %value = $round($json(%ref).value,2)
echo -ag %target %weapon %prop %value
}
alias weapons.enum {
if ($hget(cod.weapons,$1)) { return $v1 }
return $1
}
alias weapons.init {
hmake cod.weapons
hadd cod.weapons iw8_sn_crossbow CrossBow
hadd cod.weapons iw8_sn_kilo98 Kar98k
hadd cod.weapons iw8_sn_miki14 EBR-14
} But are these going to be read by something else which only supports INI? You could just save the json itself and use $json whenever you want to access something.
Last edited by Loki12583; 22/10/20 08:37 PM.
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
You could just save the json itself and use $json whenever you want to access something. This. My JSON script supports saving data to a file via the $JSON()'s toFile suffix. Here's an example of saving the URL's response to a file: $JSON(name, path/to/file.json).HttpBodyToFile Then to load that file: /JSONOpen -f name path/to/file.json
Last edited by FroggieDaFrog; 22/10/20 09:02 PM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
gonna give it a try. The reason i save it to an ini is that i know how to and im using a timer to access the api every 30min. so when ever someone does the !warzone command it reads from the ini instead of requesting new data from the api. im thinking this is better for the api then just spamming it if you would have alot of users in chat that want to know my stats.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
After thinking of it would be smarter to just read the json file. But i cant figure out where to put the save thing. i did try and put it under Cod.Stats.show and im asuming the Name is %stats $json( %stats $+ , $mircdirscripts $+ / $+ CodStats.json).HttpBodyToFile it saves the file but gives me an unknow command. So im messing something up.
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
/noop $json( %stats $+ , $mircdirscripts $+ / $+ CodStats.json).HttpBodyToFile
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Thanks that was it. ![wink wink](/images/graemlins/mirc/wink.gif) It seems it dosent overwrite the last file if it exsist or does it just overwrite if if there is any changes maybe?
Last edited by Bast; 23/10/20 06:31 AM.
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
It sounds like you don't need to keep these values in a file at all then, you have a few other options. Saving the json response to file might still be your best option, but these are worth considering. 1. Use hash tables. Parse all values for fastest lookup later. This is closest to your INI storage, and can even be saved to INI if you want to persist when mIRC is closed. /hmake weapon.stats
/hadd weapon.stats Kar98.Kills 300
/hadd weapon stats Kar98.Accuracy 45
...
var %Kar98.Kills = $hget(weapon.stats,Kar98.Kills) 2. Save json to binvar. I'm not sure exactly how much faster this would be than using a file. var %bvar = $json(%ref).HttpBodyToBvar
hadd -mb cod.responses stats %bvar
...
var %bvar = $hget(cod.responses,stats)
/JSONOpen -bd cod.response.stats %bvar
var %Kar98.Kills = $json(cod.response.stats,data,lifetime,...) 3. Don't close the json handle until you replace it. Whenever /JSONOpen is called currently the -d switch is used. Remove that, and either open it with a custom %ref name or save the returned %ref for later. Then you just access with $json(%ref,data,lifetime,stats,...) later on without having to request from the API again. You can /JSONClose on a timer to remove it later then refresh stats. Could be adding unnecessary complexity.
Last edited by Loki12583; 23/10/20 12:06 PM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
nice.
The whole reason that i want to save it to a file is that i fo example just want my own stats to be lookup and saved ever = x and the person(s) in chat should only be allowed to request fresh stats every = x So then i want to save these values either to a json with their name on it and i just calculate time to for my = x
But as i said above, i cant get it to overwrite the last file for some reason.
i have tested the open/close and got that to work.
and if you would build a DB you can add later a !compare <weaon> to my stats. But im guessing it would be better with a mysqldb for this maybe.
Last edited by Bast; 23/10/20 10:31 PM.
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
The json script will not overwrite the file if it exists, so you'll need to delete the file before making a call to $json. This is to prevent accidental overwrites. var %file = path/to/file
.remove $qt(%file)
noop $JSON(name, %file).HttpBodyToFile
Last edited by FroggieDaFrog; 23/10/20 11:12 PM.
|
|
|
|
|