|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Can someone help me with a login script. i have this. alias subc {
echo -s *** Closing Cod.Stats
sockclose cstats
echo -s *** Opening Cod.Stats
sockopen -e cstats my.callofduty.com 443
}
on *:sockopen:cstats: {
sockwrite -n $sockname GET /api/papi-client/stats/cod/v1/title/mw/platform/battle/gamer/Ancientswede $+ % $+ 232802/profile/type/warzone HTTP/1.0
sockwrite -n $sockname User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
sockwrite -n $sockname Host: my.callofduty.com
sockwrite -n $sockname Accept-Language: en-us
sockwrite -n $sockname Accept: */*
sockwrite -n $sockname
}
on *:sockread:cstats: {
if ($sockerr) {
echo -a Error.
halt
}
else {
var %temp
sockread -f %temp
echo -a %temp
}
} it works but i need to send the login/authenticated to the site so can i retrive the data, but i have no idea how to do that. i need to send this
POST Auth tokens
https://profile.callofduty.com/do_login?new_SiteId=cod
Obtain the auth tokens (atkn, rtkn) from the cookies of the response after triggering a login of a user. These tokens have a suspected lifetime of about 2 hours after which they have to be reobtained.
HEADERS
CookieXSRF-TOKEN={{XSRF-TOKEN}}
PARAMS
new_SiteIdcod
BODY formdata
username{{accountEmail}}
The e-mail address of your Activision account
password{{accountPassword}}
The password of your Activision account
remember_metrue
A boolean representing the option to save your login credentials
_csrf{{XSRF-TOKEN}}
The XSRF-TOKEN, needs to be obtained (or reobtained) if the reply throws a 403 Unauthorized error
curl --location --request POST 'https://profile.callofduty.com/do_login?new_SiteId=cod' \
--header 'Cookie: XSRF-TOKEN={{XSRF-TOKEN}}' \
--form 'username={{accountEmail}}' \
--form 'password={{accountPassword}}' \
--form 'remember_me=true' \
--form '_csrf={{XSRF-TOKEN}}'
GET CSRF-token
https://profile.callofduty.com/cod/login
Obtain a CSRF-token from the Call of Duty login form that we can send with our future requests. Without a CSRF-token in the cookies of our request headers we will be returned a 403 error (Unauthorized)
But as i said i have no idea how to send the stuff to the page so i can get the data, i know how to sort it afterwards, so if anyone can/want to help me with this it would be much appreciated.
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
You can use $urlget() to do http requests. Assuming your curl is correct you would do something such as: alias postit {
// build the body as url-encoded form parameters
bset -t &body 1 username={{accountEmail}}&password={{accountPassword}}&remember_me=true&_csrf={{XSRF-TOKEN}}
// build a list of headers, seperated by crlf, inside a bvar:
bset -t &headers 1 Content-Type: application/x-www-form-urlencoded $+ $crlf
bset -t &headers -1 Content-Length: $bvar(&body, 0) $+ $crlf
bset -t &headers -1 Cookie: XSRF-TOKEN={{XSRF-TOKEN}}
// start the request
noop $urlget(https://profile.callofduty.com/do_login?new_SiteId=cod, pb, &response, postit_response, &headers, &body)
}
alias postit_response {
var %id = $1
var %response_bvar = $urlget(%id).target
// do something with %response_bvar
echo -s >> $bvar(%response_bvar, 1-3000).text
}
Last edited by FroggieDaFrog; 17/10/20 07:22 AM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
tank you. But i dont understand that code at all ![smile smile](/images/graemlins/mirc/smile.gif) And it throws me No such identifier: $urlget But i have looked at it more and the login page is this one https://profile.callofduty.com/cod/loginwich i need to put in my mail and password. then i need to request this site after https://www.callofduty.com/api/papi-client/stats/cod/v1/title/mw/platform/battle/gamer/Ancientswede%232802/profile/type/warzone i have tried and googled it and cant find any answer at all. But looks like im able to do a POST first or am i wrong? Havent been tuching coding in 5 years and i never messed around with the sock thingy. ![smile smile](/images/graemlins/mirc/smile.gif)
Last edited by Bast; 18/10/20 01:32 AM.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
Urlget was added in version 7.56, so if you're needing help for an older version, please mention your version when asking for help. Or, if able to upgrade, try that.
Last edited by maroon; 18/10/20 04:40 AM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
o my bad,i was a couple of version off that. Did the update so im on the latest atm. That code still shows me a Invalid parameters: $bvar (line 171, twitch.mrc)
Last edited by Bast; 18/10/20 07:11 AM.
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
Your problem is likely because there was no response data. This can happen based on the http status code. You can echo $urlget(%id).reply to see the headers. But I think I've identified a problem using $urlget for this purpose. When you finally get the correct POST sent, the response is a 302 redirect which mIRC follows and eventually responds with a 200 OK. But the original response headers with the 302 are no longer available so you cannot retrieve the auth cookies. It took me a while to realize this was the problem rather than something I was doing wrong. mIRC needs to add the ability not to follow redirects; I could imagine other ways to work around this but that's probably the easiest. Until this is added you'll need to use raw sockets, use curl to obtain these cookies, or use another script like JSON-For-Mirc. Edit: Looks like jsonformirc also follows redirects after a POST?
Last edited by Loki12583; 18/10/20 09:53 PM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
i get a 403 Respons. But i have tried like alot of different login path since it seems to be multiple adresses, byt they all give me the same respons. So im guessing im getting to the wrong page? well it beats me since i have no idea to tackle this problem. The code to login should be good since its the same person who has coded the call of duty stats plugin for discord and he has documented the login process here
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
I have a proof-of-concept working: HERECurrently it's using my old script for custom sockets and JSON-For-MircI left in all the test functions and debug text. /cod.login.jfm and /cod.login.urlget both result in a 200 OK when I expect to receive a 302 Temporary Redirect. Cookie handling in the script will need to be improved regardless of which socket method is used.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
wow thats super awesome of you. if i do /cod.stats it shows me this url https://my.callofduty.com/api/papi-client/stats/cod/v1/title/mw/platform/battle/gamer/Ancientswede%232802/profile/type/warzone
redirect
method post
type binvar
target &response
alias urlget.callback
id 1046
state fail
size 0
resume 0
rcvd 0
time 469
reply /cod.login i just get the * /echo: insufficient parameters (line 86, script4.mrc) so in what way should i call the script? i have set the password and email in the vars.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
The echo error is caused when there's a blank line or a line containing only spaces. You can either do checking to avoid echoing 'nothing', or have a prefix at the front of the echo.
echo -a %temp
would change to one of these:
echo -a >>: %temp if ($remove(%temp,$chr(32)) != $null) echo -a %temp
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
The error on that specific line indicates no cookies were stored. Did you also install the JSON-For-mIRC script? You'll want that anyway to parse the json responses. If you enter these commands do they produce real values? Don't post the actual cookie values here they could be used to access your account. You should be getting a lot of debug text in your current window while these are executing. //echo -ag token: $cod.token
//echo -ag cookies: $cod.cookies Edit: Hopefully you can get the login working. I added a new function to cache and print some stats: /cod.login
/cod.stats.display
Username: Ancientswede#2802
Level: 153
Kills: 64154
Last edited by Loki12583; 19/10/20 03:54 AM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
I did mess up before it seems like. If i do a /cod.login now it shows me alot of text
HTTP/1.1 403 Forbidden
Content-Type: text/html;charset=utf-8
Content-Length: 431
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Language: en
Date: Mon, 19 Oct 2020 04:45:11 GMT
Connection: close
X-Activision-Regioncode: AB
Set-Cookie:ALOT.OF.TEXT
2
2 :: _abck=ALOT.OF.TEXT
2 :: Domain=.callofduty.com; Path=/; Expires=Tue, 19 Oct 2021 04:45:11 GMT; Max-Age=31536000; Secure
-
_abck=ALOT.OF.TEXT-1; if i do //echo -ag token: $cod.token //echo -ag cookies: $cod.cookies token: ALOT.OF.TEXTk
cookies: _abck=ALOT.OF.TEXT; on cod.stats i get url https://my.callofduty.com/api/papi-client/stats/cod/v1/title/mw/platform/battle/gamer/%232802/profile/type/warzone
redirect
method post
type binvar
target &response
alias urlget.callback
id 1065
state ok
size 0
resume 0
rcvd 148
time 1141
reply HTTP/1.1 200 OK
Content-Type: application/json
Expires: Mon, 19 Oct 2020 05:48:59 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Mon, 19 Oct 2020 05:48:59 GMT
Connection: keep-alive
Set-Cookie: API_CSRF_TOKEN=07cbdb71-3fbf-4ab3-bc62-80a612c159c9; Secure; SameSite=Strict; Path=/
response {"status":"error","data":{"type":"com.activision.mt.common.stdtools.exceptions.NoStackTraceException","message":"Not permitted: not authenticated"}} btw, the remember me thing in the code is that something that need to be there for the cookie? caus its no such box on the login page which i asume its for?
Last edited by Bast; 19/10/20 05:49 AM.
|
|
|
|
Joined: Dec 2002
Posts: 252
Fjord artisan
|
Fjord artisan
Joined: Dec 2002
Posts: 252 |
You can be given multiple cookies, all on individual "Set-Cookie:" header lines. They normally have more information than what you're showing... You can't pass back an identical cookie for this reason, there's a proper protocol to follow. For instance: Set-Cookie: item=value;Max-Age=N;Path=/ With the provided information, we have a cookie "item" with the value of "value" which expires at age N, and this cookie applies to a Path relevant to the root directory "/". If we made a request which applies to this cookies path, we must return this cookie within our own request header, minus the additional information. If our request path does NOT apply to the relative cookies acceptable path, this cookie should NOT be relayed, but in this cause, the path is "/" which is the root directory, so all paths "/some/other/location/etc.." would apply, so our response would look something like: Cookie: item=value Now what if we're delivered multiple cookies that all apply? like: Set-Cookie: item=value;Max-Age=N;Path=/ Set-Cookie: item2=value2;Max-Age=N;Path=/ Well now we must combine our request header cookies into a return (although I think it's also possible to submit multiple cookie lines too, haven't read up on http/1.1 protocol in a while) Which would look something like: Cookie: item=value; item2=value2 Your Regex capture group appears to not be greedy and find up-to the first ";" and include this within the capture, I do believe the last relayed cookie should not end in a semi-colon. I've tested this locally and watched the response headers from both Firefox and Chrome, and this is how they both appear to re-represent a stored cookie string. I haven't exploited deliberately sending a crazy amount of cookies to see how it handles what can fit in a "Cookie:" header line, to witness how it might break-up such a long string. Firefox Test:
GET /cp HTTP/1.1
Host: xxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: https://xxxx/cp/
Cookie: ClientID=xxxx; OtherData=xxxx
If-Modified-Since: Fri, 09 Mar 2018 02:34:29 GMT
Cache-Control: max-age=0
Not sure if this could be a culprit or not. Also, the value's should be unpacked (uri-compliant, the whole + for space, %XX for illegal characters, etc..) but I do believe you aren't re-packing the value from the httpd request response anyways, but that was another thought I had. I've never used JSON-4-mIRC so I can't help much beyond that, but I have done plenty of API-related things dealing with cookies over http/https with raw sockets, long before the existance of json-4-mirc and $urlget. It's not too terribly difficult if you understand http/1.1 protocol, which is quite an extensive RFC read. Also you've posted your response as "A-LOT-OF-TEXT" which makes me wonder if you might be getting any line too long errors? maybe you should be hadding these to a table with -b and saving a binvar? If you go that route, make sure to noop $hget(table,item,&bvar) to load it up, then you could /bcopy whatever data you wish to append, then once again /hadd -b it back to the table, to keep extending your cookie tokenized list.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
thanks Talon, But i dint understand anything of that ![cry cry](/images/graemlins/mirc/cry.gif) i just want to login to one page then its going to redirect me to the api page, never thought that would be so hard ![smile smile](/images/graemlins/mirc/smile.gif) maybe i have to look into a php script that can output a txt file or something instead.
Last edited by Bast; 20/10/20 12:11 AM.
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
In the remote editor, in the variable tab do you have %username and %password set? Originally my comments were missing the % in the set commands. I have not seen you post anything with the csrf token, this may indicate json-for-mirc is not working. You have "JSON For Mirc.js" in the same folder as the mrc script? Can you enter this and reply with the response? //echo -ag $jsonversion :: $cod.token But the script is working. The cookie regex is fine, it's global //g and I loop over the set-cookie values to include them in the next request. SReject is looking into changing json-for-mirc to disable redirects. I have made this change locally and can now skip my custom sockets in lieu of an entire json-for-mirc approach.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Yes i did set the username and password and i have done an ¤echo to make sure its there. and yes i have both JSON files in the mirc dir i get this on your command SReject/JSONForMirc v2.0.4000 :: UFSRAnlnfH7OI8P_1r_6iwxop5T22E7iYdLlcEAebhIij7Ky-c7rKk2iT8dJyjAk
Last edited by Bast; 20/10/20 01:44 AM.
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
SReject has updated his script to support redirect disabling, you'll have to grab the master files directly: JSON For mIRC.mrcJSON For mIRC.jsI have updated my script accordingly, $urlget and custom sockets are no longer used: CallOfDuty.mrcIt will now log you in automatically upon your first API access if cookies are not detected. Still need to add support for cookie expiration and failure handling. Just restart mIRC to start fresh and enter /cod.stats.show Ancientswede#2802
Last edited by Loki12583; 20/10/20 03:08 PM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
thanks. Now i actually got a respons Status: 200
Head: 200 OK
Cache-Control: max-age=590134
Connection: keep-alive
Connection: Transfer-Encoding
Date: Tue, 20 Oct 2020 23:47:18 GMT
Transfer-Encoding: chunked
Content-Type: text/html;charset=utf-8
Expires: Tue, 27 Oct 2020 19:42:52 GMT
Last-Modified: Tue, 20 Oct 2020 19:42:52 GMT
ETag: W/"ceeee-5b21f6fc79192-gzip"
Server: Apache/2.4.39 (Amazon) Communique/4.2.2
X-Akamai-Path-Stats: [3:103990:7043010],[1:19224:8776]
X-Activision-Regioncode: AB
X-Activision-Countrycode: SE
<!DOCTYPE HTML>
<html lang="sv">
<head>
<meta charset="UTF-8"/>
<script> but its seems to get stuck, caus i can only do that respons 1 time, then nothing happends if i try and do it more time withour restarting mirc and i dont get any values from the api page its going to next.
Last edited by Bast; 21/10/20 03:43 AM.
|
|
|
|
Joined: Jan 2004
Posts: 1,360
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 1,360 |
It looks like you're getting the 200 response after following the 302 redirect (means login request was successful). When this happens the cookies are set to $null (because none are received in the subsequent 200 response), so that explains the behavior you're seeing. But it shouldn't be following the 302 to the 200 with the latest jsonformirc, can you enter the following command? Modifying the path if you don't have these in the mirc script directory. //echo -ag $jsonversion :: $md5($mircdirscripts\Json For mIRC.js,2)
SReject/JSONForMirc v3.0.1002 :: 230784d5928a75c2fb92a6e41f983b9f Included is the current version and hash at the time of this comment.
Last edited by Loki12583; 21/10/20 01:07 PM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
then i get an error * Error accessing file: $md5
-
SReject/JSONForMirc v3.0.1002 EDITI did mess up somehwre along the line. Did a fresh install of the json and your script on the stats/login and now i got the correct respons. Damn your are awesome , BIG thank You for all the help and patience from you. You Rock So next one would be how do i get more data out of it, from what i see in the echo i only get like a 4th of all the stats.
Last edited by Bast; 21/10/20 04:57 PM.
|
|
|
|
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.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
ok i see, but wouldent it be better if there was a switch for overwrite? ![wink wink](/images/graemlins/mirc/wink.gif) But what are you thoughts on saving user stats. Should i use the hashtables and then save it to an ini file or is my thinking viable to save the json then access it?
Last edited by Bast; 23/10/20 11:17 PM.
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Why cant i grab the null value in this string? $json(%stats,data,weekly,all,properties).value the json looks like this. {
"status": "success",
"data": {
"title": "mw",
"platform": "battle",
"username": "Ancientskull#1576",
"type": "wz",
"level": 55.0,
"maxLevel": 0.0,
"levelXpRemainder": 3000.0,
"levelXpGained": 7000.0,
"prestige": 0.0,
"prestigeId": 0.0,
"maxPrestige": 0.0,
"totalXp": 960000.0,
"paragonRank": 0.0,
"paragonId": 0.0,
"s": 0.0,
"p": 0.0,
"lifetime": {
"all": {
"properties": {
"weekly": {
"all": {
"properties": null
},
"mode": {
},
"map": {
}
},
"engagement": null
}
} so there is no data for weekly so i would want it to add null to my ini, so can check it and say, hey, there is no data for weekly.
|
|
|
|
Joined: Apr 2010
Posts: 969
Hoopy frood
|
Hoopy frood
Joined: Apr 2010
Posts: 969 |
In JSON null means "no value", so the json script converts it to $null; that is, an empty string
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
ofcource, i was seeing it as a text so i tried to do an if statement with null instead of $null ![blush blush](/images/graemlins/mirc/blush.gif)
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Why cant i use this line? it always get stuck on this one even i thou i have the 4th word like that. f (($strip($4) != battle) || ($strip($4) != psn) || ($strip($4) != xbl)) { u need to type in battle,psn,xbl not $strip($4) This works just how it should. if (($strip($4) == battle) || ($strip($4) == psn) || ($strip($4) == xbl)) { What am i doing wrong? my brain might be fried atm. ![laugh laugh](/images/graemlins/mirc/laugh.gif) or cant you use "or with not equal to"
Last edited by Bast; 28/10/20 12:07 AM.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
Your first statement will always be true. Just like this will always be true:
if ( (%var != 1) || (%var != 2) )
Since a variable can't be both values, then at least 1 of them must be true. Maybe you want to do something like:
if (!$istok(battle psn xbl,$strip($4),32)) echo -a u need to type in battle,psn,xbl not $strip($4)
Or, you could do if (($strip($4) == battle) || ($strip($4) == psn) || ($strip($4) == xbl)) { do stuff } else { echo -a error }
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
Thanks maroon for that explanation. My brain felt like it melted whan i was looking att that row and felt like it should really work, but i couldent for my life figure out why. ![cool cool](/images/graemlins/mirc/cool.gif)
|
|
|
|
Joined: Nov 2011
Posts: 38
Ameglian cow
|
OP
Ameglian cow
Joined: Nov 2011
Posts: 38 |
I do have this loop that does the job. But guns has 50 entrys tactical 5 leathal 10 Question: Does this break the scipt? i dont get any error, but since their is different amount of entrys in every one! should i make a loop on every single section or is it a better way of doing things? var %i = 1 | while (%i <= $ini($shortfn($mircdirscripts) $+ %dstats $+ MW-Weapons.ini,GUNS,0)) {
if ($readini($shortfn($mircdirscripts) $+ %dstats $+ MW-Weapons.ini,GUNS,%i) == %weapon $+ ) { .msg chan}
if ($readini($shortfn($mircdirscripts) $+ %dstats $+ MW-Weapons.ini,TACTiCAL,%i) == %weapon $+ ) { .msg chan }
if ($readini($shortfn($mircdirscripts) $+ %dstats $+ MW-Weapons.ini,LETHALS,%i) == %weapon $+ ) { .msg %chan }
inc %i
} [u][/u]
|
|
|
|
|