<commit_before>/* Request.js
KC3改 API Requests

Instantiatable class to represent a single API call
Executes processing and relies on KC3Network for the triggers
*/
(function(){
	"use strict";
	
	window.KC3Request = function(har){
		// HAR Specification (v1.2) see: http://www.softwareishard.com/blog/har-12-spec/
		// Deep clone for avoiding direct references to HAR object members
		if(har){
			this.url = String(har.request.url);
			this.headers = $.extend(true, [], har.response.headers);
			this.statusCode = har.response.status;
			this.params = $.extend(true, [], har.request.postData.params);
			this.call = this.url.substring(this.url.indexOf("/kcsapi/") + 8);
			this.parsePostDataTextIfNecessary(har);
		}
		this.gameStatus = 0;
		this.response = {};
	};
	
	/**
	 * Parse the postData text in the request body instead, for these cases browser cannot do it for us:
	 *   * Redirected request after a 307 response on Chrome m72 or later
	 */
	KC3Request.prototype.parsePostDataTextIfNecessary = function(har){
		// Considered as necessary since KCSAPI is posting `application/x-www-form-urlencoded` data,
		// as long as params is undefined and text exists, ignoring the original mine-type.
		if(har.postData && !har.postData.params && har.postData.text && !this.params.length){
			// Simulate the parsing behavior browser does for HAR `postData.params`
			const decodeFormUrlencoded = (text) => {
				const result = [];
				const keyValuePairs = text.split(/&+/);
				for (const keyValuePair of keyValuePairs) {
					const keyValue = keyValuePair.split(/=/);
					// Not support yet: (Array/Dictionary) key, (fileName, contentType), comment
					// And no `decodeURI` applied, seems browser doesnot do it in HAR either
					const name = keyValue[0], value = keyValue[1];
					result.push({
						name, value
					});
				}
				return result;
			};
			this.params = decodeFormUrlencoded(har.postData.text);
		}
	};
	
	/* VALIDATE HEADERS
	
	------------------------------------------*/
	KC3Request.prototype.validateHeaders = function(){
		// If response header statusCode is not 200, means non-in-game error
		if(this.statusCode !== 200){
			// Do not trigger a catbomb box if server responds following:
			if(this.statusCode === 307){
				// Should be safe to ignore by checking if new location is game official host.
				// But the new location header value is `/kcsapi/...`, no host in it.
				// Known issue: for some browsers, next redirected request might lose some headers,
				// and cause post data can not be parsed as `x-www-form-urlencoded` properly,
				// see #parsePostDataTextIfNecessary.
				console.warn("Response temporary redirect:", this.statusCode, this.url, this.headers);
				return false;
			}
			console.warn("Response status invalid:", this.statusCode, this.url, this.headers);<commit_msg>Log more info on 307 redirect, fix typo<commit_after>/* Request.js
KC3改 API Requests

Instantiatable class to represent a single API call
Executes processing and relies on KC3Network for the triggers
*/
(function(){
	"use strict";
	
	window.KC3Request = function(har){
		// HAR Specification (v1.2) see: http://www.softwareishard.com/blog/har-12-spec/
		// Deep clone for avoiding direct references to HAR object members
		if(har){
			this.url = String(har.request.url);
			this.headers = $.extend(true, [], har.response.headers);
			this.statusCode = har.response.status;
			this.params = $.extend(true, [], har.request.postData.params);
			this.call = this.url.substring(this.url.indexOf("/kcsapi/") + 8);
			this.parsePostDataTextIfNecessary(har.request);
		}
		this.gameStatus = 0;
		this.response = {};
	};
	
	/**
	 * Parse the postData text in the request body instead, for these cases browser cannot do it for us:
	 *   * Redirected request after a 307 response on Chrome m72 or later
	 */
	KC3Request.prototype.parsePostDataTextIfNecessary = function(request){
		// Considered as necessary since KCSAPI is posting `application/x-www-form-urlencoded` data,
		// as long as params is undefined and text exists, ignoring the original mine-type.
		if(request.postData
			&& !request.postData.params && request.postData.text
			&& !this.params.length) {
			// Simulate the parsing behavior browser does for HAR `postData.params`
			const decodeFormUrlencoded = (text) => {
				const result = [];
				const keyValuePairs = text.split(/&+/);
				for (const keyValuePair of keyValuePairs) {
					const keyValue = keyValuePair.split(/=/);
					// Not support yet: (Array/Dictionary) key, (fileName, contentType), comment
					// And no `decodeURI` applied, seems browser doesnot do it in HAR either
					const name = keyValue[0], value = keyValue[1];
					result.push({
						name, value
					});
				}
				return result;
			};
			this.params = decodeFormUrlencoded(request.postData.text);
			console.warn("Request post data reparsed:", this.params, $.extend(true, {}, request.postData));
		}
	};
	
	/* VALIDATE HEADERS
	
	------------------------------------------*/
	KC3Request.prototype.validateHeaders = function(){
		// If response header statusCode is not 200, means non-in-game error
		if(this.statusCode !== 200){
			// Do not trigger a catbomb box if server responds following:
			if(this.statusCode === 307){
				// Should be safe to ignore by checking if new location is game official host.
				// But the new location header value is `/kcsapi/...`, no host in it.
				// Known issue: for some browsers, next redirected request might lose some headers,
				// and cause post data can not be parsed as `x-www-form-urlencoded` properly,
				// see #parsePostDataTextIfNecessary.
				console.warn("Response temporary redirect:", this.statusCode, this.url, this.headers, this.params);
				return false;
			}
			console.warn("Response status invalid:", this.statusCode, this.url, this.headers);
{'fraction_non_alphanumeric': 0.13167381974248926, 'fraction_numerical': 0.009785407725321889, 'mean_word_length': 3.2618873445501095, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4867840', 'n_tokens_mistral': 1998, 'n_tokens_neox': 1680, 'n_words': 550}