SHOW:
|
|
- or go back to the newest paste.
| 1 | //API ACCESS | |
| 2 | on ^*:logon:*:{
| |
| 3 | if ($network == twitch) && ($twitch(# [ $+ [ $mnick ] ]).token) {
| |
| 4 | .raw PASS oauth: $+ $v1 | |
| 5 | .raw NICK $mnick | |
| 6 | haltdef | |
| 7 | } | |
| 8 | } | |
| 9 | ||
| 10 | on @*:text:!commercial*:#:{
| |
| 11 | if ($nick isop #) twitch.commercial # $iif($2 isnum,$2) | |
| 12 | } | |
| 13 | ||
| 14 | on @*:text:/^!(topic|game)/iS:#:{
| |
| 15 | var %switch $iif($1 == !topic,status,game) | |
| 16 | if ($2 != $null) {
| |
| 17 | if ($nick isop #) twitch.topic # %switch $2- | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | alias twitch.follow {
| |
| 22 | var %user = $1, %user.chan = #$1, %target = $2, %chan = $3 | |
| 23 | inc -e %nonce | |
| 24 | var %sockname = twitch.follow. $+ %nonce | |
| 25 | ||
| 26 | hfree -w %sockname | .hmake %sockname | |
| 27 | hadd %sockname oath.token $twitch(%user.chan).token | |
| 28 | hadd %sockname request /kraken/users/ $+ %user $+ /follows/channels/ $+ %target | |
| 29 | hadd %sockname method PUT | |
| 30 | hadd %sockname data | |
| 31 | hadd %sockname chan %chan | |
| 32 | hadd %sockname target %target | |
| 33 | hadd %sockname signal twitch.follow | |
| 34 | sockopen -e %sockname api.twitch.tv 443 | |
| 35 | } | |
| 36 | ||
| 37 | on *:signal:twitch.follow:{
| |
| 38 | var %err = $1, %sockname = $2, %header = $3, %data = $4 | |
| 39 | var %chan = $hget(%sockname,chan) | |
| 40 | ||
| 41 | if (* 200 OK iswm $read(%header,n,1)) $iif(%chan,msg %chan,echo -ag) Successfully followed $json(%data,channel,display_name) | |
| 42 | else $iif(%chan,msg %chan,echo -ag) Could not follow $hget(%sockname,target) | |
| 43 | ||
| 44 | hfree -w %sockname | |
| 45 | if ($isfile(%header)) .remove %header | |
| 46 | if ($isfile(%data)) .remove %data | |
| 47 | } | |
| 48 | ||
| 49 | alias followers.update {
| |
| 50 | if (-* iswm $1) {
| |
| 51 | var %switches = $1 | |
| 52 | tokenize 32 $2- | |
| 53 | } | |
| 54 | var %chan = #$$1, %limit = $iif($2,$2,25), %offset = $iif($3,$3,0) | |
| 55 | var %sockname = twitch.followers. $+ $ticks | |
| 56 | hfree -w %sockname | .hmake %sockname | |
| 57 | hadd %sockname chan %chan | |
| 58 | hadd %sockname limit %limit | |
| 59 | hadd %sockname offset %offset | |
| 60 | hadd %sockname request /kraken/channels/ $+ $mid(%chan,2-) $+ /follows?limit= $+ %limit $+ &offset= $+ %offset | |
| 61 | hadd %sockname method GET | |
| 62 | hadd %sockname signal followers.update | |
| 63 | if (s isin %switches) hadd %sockname show 1 | |
| 64 | if (!$hget(followers. $+ %chan)) hadd %sockname init 1 | |
| 65 | sockopen -e %sockname api.twitch.tv 443 | |
| 66 | return %sockname | |
| 67 | } | |
| 68 | ||
| 69 | on *:signal:followers.update:{
| |
| 70 | var %err = $1, %sockname = $2, %header = $3, %data = $4 | |
| 71 | var %chan = $hget(%sockname,chan), %init = $hget(%sockname,init), %show = $hget(%sockname,show) | |
| 72 | ||
| 73 | if (* 200 OK iswm $read(%header,n,1)) {
| |
| 74 | if (!$hget(followers. $+ %chan)) {
| |
| 75 | .hmake -s followers. $+ %chan $iif($calc($json(%data,_total) / 10) > 100,$v1,$v2) | |
| 76 | if ($ini(followers.ini,%chan,0) > 0) hload -i followers. $+ %chan followers.ini %chan | |
| 77 | } | |
| 78 | ||
| 79 | var %i = 0, %n = $json(%data,follows).count, %new.count | |
| 80 | while (%i < %n) {
| |
| 81 | var %name = $json(%data,follows,%i,user,name) | |
| 82 | var %display_name = $json(%data,follows,%i,user,display_name) | |
| 83 | if (!$hget(followers. $+ %chan,%name)) {
| |
| 84 | hadd followers. $+ %chan %name 1 | |
| 85 | if (!%init) && (%show) {
| |
| 86 | set -nz %followers. $+ %chan %followers. [ $+ [ %chan ] ] %display_name | |
| 87 | if ($calc($len(%followers. [ $+ [ %chan ] ]) + $len(%display_name)) > 350) {
| |
| 88 | var %msg = Welcome to our new follower $+ $iif($numtok(%followers. [ $+ [ %chan ] ],32) > 1,s:,:) $regsubex(%followers. [ $+ [ %chan ] ],/( $+ $chr(32) $+ )/g,$iif(\n == \0,$iif(\0 > 2,$chr(44),$chr(32)) and $chr(32),$chr(44) $+ $chr(32))) $+ ! | |
| 89 | .timer 1 $iif(%flood.protection,$v1,0) msg %chan $safe(%msg) | |
| 90 | inc -z %flood.protection 5 | |
| 91 | unset %followers. [ $+ [ %chan ] ] | |
| 92 | } | |
| 93 | } | |
| 94 | inc %new.count | |
| 95 | } | |
| 96 | else break | |
| 97 | inc %i | |
| 98 | } | |
| 99 | ||
| 100 | if (%new.count == $hget(%sockname,limit)) {
| |
| 101 | followers.update %chan 100 $calc($hget(%sockname,limit) + $hget(%sockname,offset)) | |
| 102 | var %next = $result | |
| 103 | if (%init) hadd %next init 1 | |
| 104 | if (%show) hadd %next show 1 | |
| 105 | } | |
| 106 | else {
| |
| 107 | if (!%init) && (%show) && (%new.count) {
| |
| 108 | var %msg = Welcome to our new follower $+ $iif($numtok(%followers. [ $+ [ %chan ] ],32) > 1,s:,:) $regsubex(%followers. [ $+ [ %chan ] ],/( $+ $chr(32) $+ )/g,$iif(\n == \0,$iif(\0 > 2,$chr(44),$chr(32)) and $chr(32),$chr(44) $+ $chr(32))) $+ ! | |
| 109 | .timer 1 $iif(%flood.protection,$v1,0) msg %chan $safe(%msg) | |
| 110 | inc -z %flood.protection 5 | |
| 111 | } | |
| 112 | unset %followers. [ $+ [ %chan ] ] | |
| 113 | if ($hget(followers. $+ %chan)) hsave -i followers. $+ %chan followers.ini %chan | |
| 114 | } | |
| 115 | } | |
| 116 | ||
| 117 | hfree -w %sockname | |
| 118 | if ($isfile(%header)) .remove %header | |
| 119 | if ($isfile(%data)) .remove %data | |
| 120 | } | |
| 121 | ||
| 122 | alias twitch.commercial {
| |
| 123 | var %chan = #$$1, %length = $2 | |
| 124 | var %sockname = twitch.topic. $+ $ticks | |
| 125 | hfree -w %sockname | .hmake %sockname | |
| 126 | hadd %sockname oath.token $twitch(%chan).token | |
| 127 | hadd %sockname method POST | |
| 128 | hadd %sockname request /kraken/channels/ $+ $mid(%chan,2-) $+ /commercial | |
| 129 | hadd %sockname signal twitch.commercial | |
| 130 | if (%length) hadd %sockname data length= $+ %length | |
| 131 | sockopen -e %sockname api.twitch.tv 443 | |
| 132 | set -z % [ $+ [ # $+ .commercial ] ] 480 | |
| 133 | set % [ $+ [ # $+ .titlebar ] ] $window(%chan).title | |
| 134 | .timer. $+ # $+ .commercial 480 1 titlebar.update.commercial @ [ $+ [ $window(%chan).wid ] ] | |
| 135 | } | |
| 136 | ||
| 137 | on *:signal:twitch.commercial:{
| |
| 138 | var %err = $1, %sockname = $2, %header = $3, %data = $4 | |
| 139 | var %chan = $hget(%sockname,chan) | |
| 140 | ||
| 141 | if (* 2* !iswm $read(%header,n,1)) {
| |
| 142 | twitch.debug Error: $iif($v2,$v1,could not read header) | |
| 143 | var %error = $json(%data,error) | |
| 144 | var %message = $json(%data,message) | |
| 145 | if (%error != $null) && (%message != $null) { twitch.debug Error: %error $+ , %message }
| |
| 146 | } | |
| 147 | ||
| 148 | hfree -w %sockname | |
| 149 | if ($isfile(%header)) .remove %header | |
| 150 | if ($isfile(%data)) .remove %data | |
| 151 | } | |
| 152 | ||
| 153 | alias titlebar.update.commercial {
| |
| 154 | if (% [ $+ [ # $+ .commercial ] ] > 0) { titlebar $$1 - Commercial available in $duration($v1) }
| |
| 155 | else { titlebar $$1 % [ $+ [ # $+ .titlebar ] ] | unset % [ $+ [ # $+ .titlebar ] ] | .timer [ $+ [ $ctimer ] ] off }
| |
| 156 | } | |
| 157 | ||
| 158 | alias twitch.topic {
| |
| 159 | var %chan = $1, %switch = $2, %topic = 3- | |
| 160 | var %sockname = twitch.topic. $+ $ticks | |
| 161 | hfree -w %sockname | .hmake %sockname | |
| 162 | hadd %sockname chan %chan %switch | |
| 163 | hadd %sockname oath.token $twitch(%chan).token | |
| 164 | hadd %sockname request /kraken/channels/ $+ $mid(%chan,2-) | |
| 165 | if (%topic != $null) {
| |
| 166 | hadd %sockname method PUT | |
| 167 | hadd %sockname data channel[ $+ $switch $+ ]= $+ $urlencode(%topic) | |
| 168 | hadd %sockname signal topic.set | |
| 169 | } | |
| 170 | else {
| |
| 171 | hadd %sockname method GET | |
| 172 | hadd %sockname signal topic.get | |
| 173 | } | |
| 174 | sockopen -e %sockname api.twitch.tv 443 | |
| 175 | } | |
| 176 | ||
| 177 | on *:signal:topic.get:{
| |
| 178 | var %err = $1, %sockname = $2, %header = $3, %data = $4, %chan = $5, %switch = $6 | |
| 179 | var %chan = $hget(%sockname,chan) | |
| 180 | ||
| 181 | if (* 200 OK iswm $read(%header,n,1)) msg %chan %switch $+ : $json(%data,%switch) | |
| 182 | else msg %chan Could not get %switch $+ ! | |
| 183 | ||
| 184 | hfree -w %sockname | |
| 185 | if ($isfile(%header)) .remove %header | |
| 186 | if ($isfile(%data)) .remove %data | |
| 187 | } | |
| 188 | ||
| 189 | on *:signal:topic.set:{
| |
| 190 | var %err = $1, %sockname = $2, %header = $3, %data = $4 | |
| 191 | var %chan = $hget(%sockname,chan) | |
| 192 | ||
| 193 | if (* 200 OK iswm $read(%header,n,1)) msg %chan Status set: $json(%data,status) | |
| 194 | else msg %chan Could not set status. | |
| 195 | ||
| 196 | hfree -w %sockname | |
| 197 | .remove %header | .remove %data | |
| 198 | } | |
| 199 | ||
| 200 | alias twitch.auth.request {
| |
| 201 | var %chan = #$$1, %user = $mid(%chan,2-) | |
| 202 | var %client_id = $twitch(%chan).client_id | |
| 203 | var %secret = $twitch(%chan).secret | |
| 204 | var %redirect_uri = $twitch(%chan).redirect_uri | |
| 205 | var %scope = $twitch(%chan).scope_request | |
| 206 | ||
| 207 | if (!$sock(twitch.auth.request)) socklisten -d 127.0.0.1 twitch.auth.request 80 | |
| 208 | if (%secret) url $+(https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id=,%client_id,&redirect_uri=,%redirect_uri,&scope=,%scope,&state=,%user) | |
| 209 | else url $+(https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id=,%client_id,&redirect_uri=,%redirect_uri,&scope=,%scope,&state=,%user) | |
| 210 | } | |
| 211 | ||
| 212 | on *:socklisten:twitch.auth.request:{
| |
| 213 | var %sockname = twitch.auth.request. $+ $ticks | |
| 214 | if ($sock(%sockname)) return | |
| 215 | ||
| 216 | hfree -w %sockname | .hmake %sockname | |
| 217 | hadd %sockname header.signal twitch.auth.request | |
| 218 | ||
| 219 | sockaccept %sockname | |
| 220 | } | |
| 221 | ||
| 222 | on *:signal:twitch.auth.request:{
| |
| 223 | var %err = $1, %sockname = $2, %header = $3 | |
| 224 | var %request = $read(%header,n,1) | |
| 225 | ||
| 226 | if ($regex(%request,^GET / HTTP)) {
| |
| 227 | var %document = <!doctype html><html><head><script>var x = null; x = new XMLHttpRequest(); x.open("GET", "/?" + document.location.hash.substring(1), false); x.send(null); document.write(x.responseText);</script></head></html>
| |
| 228 | socket.respond %sockname %document | |
| 229 | } | |
| 230 | elseif ($regex(%request,^GET /\?access_token=(\w+).*&scope=([\w+]+).*&state=(\w+))) {
| |
| 231 | var %access_token = $regml(1), %scope = $regml(2), %chan = # [ $+ [ $regml(3) ] ] | |
| 232 | ||
| 233 | socket.respond %sockname Successfully received token, return to mIRC. | |
| 234 | sockclose twitch.auth.request | |
| 235 | ||
| 236 | writeini twitch.ini %chan token %access_token | |
| 237 | ||
| 238 | remini twitch.ini %chan $+ .scope | |
| 239 | var %i = 1, %n = $numtok(%scope,43) | |
| 240 | while (%i <= %n) {
| |
| 241 | writeini twitch.ini %chan $+ .scope $gettok(%scope,%i,43) 1 | |
| 242 | inc %i | |
| 243 | } | |
| 244 | } | |
| 245 | elseif ($regex(%request,^GET /\?code=(\w+).*&state=(\w+))) {
| |
| 246 | var %code = $regml(1), %chan = # [ $+ [ $regml(2) ] ] | |
| 247 | ||
| 248 | twitch.token.request %chan %code %sockname | |
| 249 | sockclose twitch.auth.request | |
| 250 | } | |
| 251 | elseif ($regex(%request,^GET /favicon.ico HTTP)) {
| |
| 252 | sockwrite -n %sockname HTTP/1.1 404 Not Found | |
| 253 | sockwrite -n %sockname Connection: close | |
| 254 | sockwrite -n %sockname $crlf | |
| 255 | } | |
| 256 | else socket.respond %sockname Could not retrieve token. | |
| 257 | ||
| 258 | if ($isfile(%header)) .remove %header | |
| 259 | } | |
| 260 | ||
| 261 | alias twitch.token.request {
| |
| 262 | var %chan = #$$1, %code = $$2, %response.sockname = $$3 | |
| 263 | var %client_id = $twitch(%chan).client_id | |
| 264 | var %client_secret = $twitch(%chan).secret | |
| 265 | var %redirect_uri = $twitch(%chan).redirect_uri | |
| 266 | var %data = $+(client_id=,%client_id,&client_secret=,%client_secret,&grant_type=authorization_code,&redirect_uri=,%redirect_uri,&code=,%code) | |
| 267 | ||
| 268 | var %sockname = twitch.token.request. $+ $ticks | |
| 269 | hfree -w %sockname | .hmake %sockname | |
| 270 | hadd %sockname method POST | |
| 271 | hadd %sockname request /kraken/oauth2/token | |
| 272 | hadd %sockname data %data | |
| 273 | hadd %sockname signal twitch.token.request | |
| 274 | hadd %sockname chan %chan | |
| 275 | hadd %sockname twitch.code.respond %response.sockname | |
| 276 | sockopen -e %sockname api.twitch.tv 443 | |
| 277 | } | |
| 278 | ||
| 279 | on *:signal:twitch.token.request:{
| |
| 280 | var %err = $1, %sockname = $2, %header = $3, %data = $4 | |
| 281 | var %chan = $hget(%sockname,chan) | |
| 282 | ||
| 283 | if (* 200 OK iswm $read(%header,n,1)) {
| |
| 284 | writeini twitch.ini %chan token $json(%data,access_token) | |
| 285 | ||
| 286 | remini twitch.ini %chan $+ .scope | |
| 287 | var %i = 0, %n = $json(%data,scope).count | |
| 288 | while (%i < %n) {
| |
| 289 | writeini twitch.ini %chan $+ .scope $json(%data,scope,%i) 1 | |
| 290 | inc %i | |
| 291 | } | |
| 292 | ||
| 293 | socket.respond $hget(%sockname,twitch.code.respond) Successfully received token, return to mIRC. | |
| 294 | } | |
| 295 | else {
| |
| 296 | socket.respond $hget(%sockname,twitch.code.respond) Could not retrieve token. | |
| 297 | } | |
| 298 | ||
| 299 | sockclose -w twitch.auth.request | |
| 300 | hfree -w %sockname | |
| 301 | if ($isfile(%header)) .remove %header | |
| 302 | if ($isfile(%data)) .remove %data | |
| 303 | } | |
| 304 | ||
| 305 | on *:sockopen:twitch.*:{
| |
| 306 | var %a = sockwrite -n $sockname | |
| 307 | ||
| 308 | %a $hget($sockname,method) $hget($sockname,request) HTTP/1.1 | |
| 309 | %a Host: api.twitch.tv | |
| 310 | %a Connection: close | |
| 311 | %a Accept: application/vnd.twitchtv.v2+json | |
| 312 | if ($hget($sockname,oath.token) != $null) %a Authorization: OAuth $v1 | |
| 313 | if ($hfind($sockname,data).item) {
| |
| 314 | %a Content-Type: application/x-www-form-urlencoded | |
| 315 | %a Content-Length: $len($hget($sockname,data)) | |
| 316 | } | |
| 317 | %a $+($crlf,$hget($sockname,data)) | |
| 318 | } | |
| 319 | ||
| 320 | on *:sockread:twitch.*:{
| |
| 321 | var %headerfile = $sockname $+ .header.txt | |
| 322 | var %datafile = $sockname $+ .data.txt | |
| 323 | ||
| 324 | if (!$sock($sockname).mark) {
| |
| 325 | var %header | sockread %header | |
| 326 | while (%header != $null) {
| |
| 327 | write %headerfile %header | |
| 328 | if (%header == Transfer-Encoding: chunked) {
| |
| 329 | hadd $sockname chunk-size 0 | |
| 330 | } | |
| 331 | sockread %header | |
| 332 | } | |
| 333 | if ($sockbr) {
| |
| 334 | if ($hget($sockname,header.signal)) .signal $v1 0 $sockname %headerfile | |
| 335 | sockmark $sockname $true | |
| 336 | } | |
| 337 | } | |
| 338 | if ($sock($sockname).mark) {
| |
| 339 | var %chunk | |
| 340 | if ($hget($sockname,chunk-size) == 0) {
| |
| 341 | sockread %chunk | |
| 342 | if ($base(%chunk,16,10) !isnum) sockread %chunk | |
| 343 | hadd $sockname chunk-size $base(%chunk,16,10) | |
| 344 | if ($hget($sockname,chunk-size) == 0) {
| |
| 345 | sockread %chunk | |
| 346 | return | |
| 347 | } | |
| 348 | } | |
| 349 | sockread $hget($sockname,chunk-size) &read | |
| 350 | while ($sockbr) {
| |
| 351 | if ($hget($sockname,chunk-size) != 0) bwrite %datafile -1 -1 &read | |
| 352 | if ($hget($sockname,chunk-size)) hdec $sockname chunk-size $sockbr | |
| 353 | if ($hget($sockname,chunk-size) == 0) {
| |
| 354 | sockread %chunk | |
| 355 | if ($base(%chunk,16,10) isnum) %chunk = $v1 | |
| 356 | else {
| |
| 357 | sockread %chunk | |
| 358 | if ($base(%chunk,16,10) isnum) %chunk = $v1 | |
| 359 | } | |
| 360 | if (%chunk isnum) {
| |
| 361 | hadd $sockname chunk-size %chunk | |
| 362 | if (%chunk == 0) sockread %chunk | |
| 363 | } | |
| 364 | } | |
| 365 | sockread $hget($sockname,chunk-size) &read | |
| 366 | } | |
| 367 | } | |
| 368 | } | |
| 369 | ||
| 370 | on *:sockclose:twitch.*:{
| |
| 371 | var %header = $sockname $+ .header.txt | |
| 372 | var %data = $sockname $+ .data.txt | |
| 373 | var %signal = $hget($sockname,signal) | |
| 374 | ||
| 375 | if (%signal) .signal %signal 0 $sockname %header %data | |
| 376 | else {
| |
| 377 | hfree -w $sockname | |
| 378 | if ($isfile(%header)) .remove %header | |
| 379 | if ($isfile(%data)) .remove %data | |
| 380 | } | |
| 381 | } | |
| 382 | ||
| 383 | alias -l twitch {
| |
| 384 | if ($1) && ($readini(twitch.ini,n,$1,$prop)) { return $v1 }
| |
| 385 | else return $readini(twitch.ini,n,global,$prop) | |
| 386 | } | |
| 387 | ||
| 388 | alias twitch.setup {
| |
| 389 | var %chan = $iif($1,$1,# [ $+ [ $mnick ] ]) | |
| 390 | var %scopes = chat_login+channel_read+channel_editor+channel_commercial+channel_subscriptions+channel_check_subscription+user_follows_edit | |
| 391 | ||
| 392 | writeini twitch.ini global redirect_uri http://localhost/ | |
| 393 | writeini twitch.ini global scope_request %scopes | |
| 394 | if (!$twitch(%chan).client_id) writeini twitch.ini %chan client_id PASTE_ID_HERE | |
| 395 | ||
| 396 | flushini twitch.ini | |
| 397 | run twitch.ini | |
| 398 | } | |
| 399 | ||
| 400 | menu channel {
| |
| 401 | $iif(!$isfile(twitch.ini),Twitch Setup) : twitch.setup # | |
| 402 | $iif($twitch(#).client_id && !$twitch(#).token,Request Token) : twitch.auth.request # | |
| 403 | ||
| 404 | $iif($twitch(#).token, Commercial) | |
| 405 | .$iif(% [ $+ [ # $+ .commercial ] ],$style(2)) 30 seconds:twitch.commercial # 30 | |
| 406 | .$iif(% [ $+ [ # $+ .commercial ] ],$style(2)) 60 seconds:twitch.commercial # 60 | |
| 407 | .$iif(% [ $+ [ # $+ .commercial ] ],$style(2)) 90 seconds:twitch.commercial # 90 | |
| 408 | ||
| 409 | $iif($twitch(#).token, Followers) | |
| 410 | .Welcome now:followers.update -s # | |
| 411 | .$iif($timer(.followers. $+ #).delay == 300000,$style(1)) 5 minute interval:if ($timer(.followers. $+ #).delay == 300000) .timer.followers. $+ # off | else .timer.followers. $+ # 0 300 followers.update -s # | |
| 412 | .$iif($timer(.followers. $+ #).delay == 600000,$style(1)) 10 minute interval:if ($timer(.followers. $+ #).delay == 600000) .timer.followers. $+ # off | else .timer.followers. $+ # 0 600 followers.update -s # | |
| 413 | .$iif($timer(.followers. $+ #).delay == 1800000,$style(1)) 30 minute interval:if ($timer(.followers. $+ #).delay == 1800000) .timer.followers. $+ # off | else .timer.followers. $+ # 0 1800 followers.update -s # | |
| 414 | ||
| 415 | $iif($twitch(#).token,Topic) : twitch.topic # $$?="Enter topic:" | |
| 416 | ||
| 417 | $iif($twitch(#).token,Renew Token) : twitch.auth.request # | |
| 418 | } | |
| 419 | ||
| 420 | alias -l twitch.debug {
| |
| 421 | if (!$window(@Twitch.tv)) window -e2hk0xz @Twitch.tv | |
| 422 | echo -i2t @Twitch.tv $1- | |
| 423 | } | |
| 424 | ||
| 425 | alias -l socket.respond {
| |
| 426 | var %sockname = $$1, %data = $2- | |
| 427 | sockwrite -n %sockname HTTP/1.1 200 OK | |
| 428 | sockwrite -n %sockname Connection: close | |
| 429 | sockwrite -n %sockname Content-Length: $len(%data) | |
| 430 | sockwrite -n %sockname $+($crlf,%data) | |
| 431 | } | |
| 432 | ||
| 433 | alias safe return $!decode( $encode($1,m) ,m) | |
| 434 | alias -l urlencode return $regsubex($1-,/([^A-Z0-9])/gi,$+(%,$base($asc(\1),10,16))) |