mIRC Home    About    Download    Register    News    Help

Print Thread
Page 2 of 3 1 2 3
Joined: Jan 2004
Posts: 1,358
L
Hoopy frood
Offline
Hoopy frood
L
Joined: Jan 2004
Posts: 1,358
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:

Code
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
Offline
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: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Some useful info about my JSON For Mirc script:

Explaination of what JSON is and JSON for mIRC Reference


I am SReject
My Stuff
Joined: Nov 2011
Posts: 38
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
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
Code
$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
Code
"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
F
Hoopy frood
Offline
Hoopy frood
F
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


I am SReject
My Stuff
Joined: Nov 2011
Posts: 38
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
Joined: Nov 2011
Posts: 38

Last edited by Bast; 22/10/20 04:24 AM.
Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
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:

Code
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.

I am SReject
My Stuff
Joined: Nov 2011
Posts: 38
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
Joined: Nov 2011
Posts: 38
right now i got it when i see it in the format. whistle


You are an awesome person who has helped alot, dont know how you coop with us noobs. grin

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
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Originally Posted by Bast
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.


I am SReject
My Stuff
Joined: Nov 2011
Posts: 38
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
Joined: Nov 2011
Posts: 38
im making so all values is saved to an ini file.
looks like this
Code
    ;;-------------------;;
    ;;      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

Code
    ;;-------------------;;
    ;;      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
Offline
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.

Code
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,358
L
Hoopy frood
Offline
Hoopy frood
L
Joined: Jan 2004
Posts: 1,358
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:

Code
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
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Originally Posted by Loki12583
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:
Code
$JSON(name, path/to/file.json).HttpBodyToFile


Then to load that file:
Code
/JSONOpen -f name path/to/file.json

Last edited by FroggieDaFrog; 22/10/20 09:02 PM.

I am SReject
My Stuff
Joined: Nov 2011
Posts: 38
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
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
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
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
Code
$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
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Code
/noop $json( %stats $+ , $mircdirscripts $+ / $+ CodStats.json).HttpBodyToFile


I am SReject
My Stuff
Joined: Nov 2011
Posts: 38
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
Joined: Nov 2011
Posts: 38
Thanks that was it. wink

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,358
L
Hoopy frood
Offline
Hoopy frood
L
Joined: Jan 2004
Posts: 1,358
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.
Code
/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.
Code
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
B
Bast Offline OP
Ameglian cow
OP Offline
Ameglian cow
B
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
F
Hoopy frood
Offline
Hoopy frood
F
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.

Code
var %file = path/to/file
.remove $qt(%file)
noop $JSON(name, %file).HttpBodyToFile

Last edited by FroggieDaFrog; 23/10/20 11:12 PM.

I am SReject
My Stuff
Page 2 of 3 1 2 3

Link Copied to Clipboard