NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name U2 Reward UC Calculator (Mods)
// @version 0.22
// @description Calc Calc Calc.
// @author 葛平改
// @license MIT
// @match https://u2.dmhy.org/forums.php?*action=viewtopic*
// @require http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.0.0.min.js
// @updateURL https://openuserjs.org/meta/bgli100/U2_Reward_UC_Calculator_(Mods).meta.js
// @downloadURL https://openuserjs.org/install/bgli100/U2_Reward_UC_Calculator_(Mods).user.js
// @grant none
// ==/UserScript==
(function() {
'use strict';
const THREAD_TITLE_PATTEN = /^Get the UCoin Bonus \| 自购发布奖励申请帖$/i; //匹配帖子标题的正则表达式. 该脚本只在符合条件的帖子里运行
const POST_PATTEN = /(Reward request|奖励申请)/i; //只在匹配左侧正则表达式的回复内运行
const CATEGORY_PATTEN = /^(Category|分类)$/i; //匹配左侧正则表达式的行是分类行, 以下同理
const BD_COUNTRY_CODE_PATTEN = /^(Country code|国家代码)$/i; //BD分类 国家代码
const BD_MAIN_BD_PATTEN = /^(# of main BDs|正片BD数)$/i; //BD分类 正片BD数
const BD_ACCUMULATED_PATTEN = /^(Accumulated volumes|累积卷数)$/i; //BD分类 累积卷数
const BD_SCAN_PATTEN = /^(# of images scanned|扫图数)$/i; //BD分类 扫图数
const BD_TOKUTEN_PATTEN = /^(# of tokuten discs\(CD, BD, DVD, etc\.\)|特典碟数\(包括CD, BD, DVD等\))$/i; //BD分类 特典碟数(包括CD, BD, DVD等)
const BD_BASE_CREDIT = 60000;
const BD_EXTRA_DISK_CREDIT = 15000;
const BD_TOKUTEN_FACTOR = 0.15;
const BD_ACCUMULATED_FACTOR = 0.1;
const BD_COUNTRY_JPN_FACTOR = 1;
const BD_COUNTRY_OTHER_FACTOR = 0.1;
const BD_COMPLETE_CREDIT = 60000;
const BD_SCAN_LIMITS = [20, 60, 200, 400];
const BD_SCAN_FACTORS = [0.005, 0.002, 0.001, 0.0005, 0.0002];
const DVD_COUNTRY_CODE_PATTEN = BD_COUNTRY_CODE_PATTEN; //DVD分类 国家代码
const DVD_MAIN_DVD_PATTEN = /^(# of main DVDs|正片DVD数)$/i; //DVD分类 正片DVD数
const DVD_ACCUMULATED_PATTEN = BD_ACCUMULATED_PATTEN; //DVD分类 累积卷数
const DVD_SCAN_PATTEN = BD_SCAN_PATTEN; //DVD分类 扫图数
const DVD_TOKUTEN_PATTEN = BD_TOKUTEN_PATTEN; //DVD分类 特典碟数(包括CD, BD, DVD等)
const DVD_BASE_CREDIT = 25000;
const DVD_EXTRA_DISK_CREDIT = 6000;
const DVD_TOKUTEN_FACTOR = BD_TOKUTEN_FACTOR;
const DVD_ACCUMULATED_FACTOR = BD_ACCUMULATED_FACTOR;
const DVD_COUNTRY_JPN_FACTOR = BD_COUNTRY_JPN_FACTOR;
const DVD_COUNTRY_OTHER_FACTOR = BD_COUNTRY_OTHER_FACTOR;
const DVD_SCAN_LIMITS = BD_SCAN_LIMITS;
const DVD_SCAN_FACTORS = BD_SCAN_FACTORS;
const CD_SCAN_PATTEN = BD_SCAN_PATTEN; //CD分类 扫图数
const CD_TOKUTEN_PATTEN = BD_TOKUTEN_PATTEN; //CD分类 特典碟数(包括CD, BD, DVD等)
const CD_TYPE_PATTEN = /^(Type|类型)$/i; //CD分类 类型
const CD_SINGLE_BASE_CREDIT = 25000;
const CD_DRAMA_BASE_CREDIT = 35000;
const CD_ALBUM_OST_BASE_CREDIT = 45000;
const CD_TOKUTEN_FACTOR = 0.20;
const CD_SCAN_LIMITS = [20, 60, 200];
const CD_SCAN_FACTORS = [0.015, 0.006, 0.003, 0.001];
const EXTRA_SCAN_PATTEN = BD_SCAN_PATTEN; //周边分类 扫图数
const EXTRA_TOKUTEN_PATTEN = BD_TOKUTEN_PATTEN; //周边分类 特典碟数(包括CD, BD, DVD等)
const EXTRA_BASE_CREDIT = 55000;
const EXTRA_TOKUTEN_FACTOR = 0.2;
const EXTRA_SCAN_LIMITS = CD_SCAN_LIMITS;
const EXTRA_SCAN_FACTORS = CD_SCAN_FACTORS;
//除非你非常清楚你在干啥否则不要修改下面的部分
const TO_BE_REPLACED = '[to_be_replaced]';
const THREAD_TITLE_SELECTOR = '.main>tbody>tr>td>h1>span';
const POST_SELECTOR = '.post-body';
const POST_TO_CONTENT_SELECTOR = 'span';
const CHECK_AREA_HTML = "<br><input type='checkbox' class='UCRewardDupe'>DUPE" +
"<input type='checkbox' class='UCRewardComplete'>完结奖励" +
"<input class='UCRewardCalc' type='button' value='通过申请, 计算数额' data='" + TO_BE_REPLACED + "'>";
const POST_ID_PATTEN = /^pid(\d+)body$/;
const TORRENT_ID_PATTEN = /https:\/\/u2\.dmhy\.org\/details\.php\?id\=(\d+)/;
if(!THREAD_TITLE_PATTEN.test($(THREAD_TITLE_SELECTOR).html())) {
console.log("Thread title didn't match.");
return;
}
var D;
var scanFactor = function(value, limits, factors) {
var ret = 0;
limits.push(Number.POSITIVE_INFINITY);
for(var i = 0; i < limits.length; i++){
if(value >= limits[i])
ret += (limits[i] - (i === 0 ? 0 : limits[i - 1])) * factors[i];
else {
ret += (value - (i === 0 ? 0 : limits[i - 1])) * factors[i];
break;
}
}
return ret;
};
var findValue = function(arr, patten, type = 'int') {
var ret = false, tmp;
arr.forEach(function (curr) {
if(patten.test(curr[0])) {
switch(type){
case 'str':
ret = curr[1].trim().replace(' ', '');
break;
case 'int':
tmp = parseInt(curr[1].trim().replace(' ', ''), 10);
if(tmp >= 0)
ret = tmp;
break;
default: break;
}
}
});
console.log(ret);
return ret;
};
var doCalc = function(content, complete, dupe, time) {
var ret = false;
content = content.split("<br>").map(function(curr) {
return curr.split(':');
});
var countryCode, main, scan, historyVolume, tokuten, type, cat = findValue(content, CATEGORY_PATTEN, 'str');
cat = cat ? cat.toUpperCase() : false;
switch (cat) {
case 'BD':
if(!([countryCode = findValue(content, BD_COUNTRY_CODE_PATTEN, 'str'),
main = findValue(content, BD_MAIN_BD_PATTEN),
scan = findValue(content, BD_SCAN_PATTEN),
historyVolume = findValue(content, BD_ACCUMULATED_PATTEN),
tokuten = findValue(content, BD_TOKUTEN_PATTEN)].every(elem => elem !== false)))
return false;
if(historyVolume < 1 || main < 1)
return false;
countryCode = countryCode === 'JPN' ? BD_COUNTRY_JPN_FACTOR : BD_COUNTRY_OTHER_FACTOR;
scan = scanFactor(scan, BD_SCAN_LIMITS, BD_SCAN_FACTORS);
complete = complete ? BD_COMPLETE_CREDIT : 0;
ret = BD_BASE_CREDIT + BD_EXTRA_DISK_CREDIT * (main - 1);
if(!dupe) {
ret *= 1 + scan + tokuten * BD_TOKUTEN_FACTOR + (historyVolume - 1) * BD_ACCUMULATED_FACTOR;
ret += complete;
} else
ret *= scan + tokuten * BD_TOKUTEN_FACTOR;
ret *= countryCode;
break;
case 'DVD':
if(!([countryCode = findValue(content, DVD_COUNTRY_CODE_PATTEN, 'str'),
main = findValue(content, DVD_MAIN_DVD_PATTEN),
scan = findValue(content, DVD_SCAN_PATTEN),
historyVolume = findValue(content, DVD_ACCUMULATED_PATTEN),
tokuten = findValue(content, DVD_TOKUTEN_PATTEN)].every(elem => elem !== false)))
return false;
if(historyVolume < 1 || main < 1)
return false;
countryCode = countryCode === 'JPN' ? DVD_COUNTRY_JPN_FACTOR : DVD_COUNTRY_OTHER_FACTOR;
scan = scanFactor(scan, DVD_SCAN_LIMITS, DVD_SCAN_FACTORS);
ret = DVD_BASE_CREDIT + DVD_EXTRA_DISK_CREDIT * (main - 1);
if(!dupe)
ret *= 1 + scan + tokuten * DVD_TOKUTEN_FACTOR + (historyVolume - 1) * DVD_ACCUMULATED_FACTOR;
else
ret *= scan + tokuten * DVD_TOKUTEN_FACTOR;
ret *= countryCode;
break;
case 'CD':
case 'HI-RES':
if(!([scan = findValue(content, CD_SCAN_PATTEN),
tokuten = findValue(content, CD_TOKUTEN_PATTEN),
type = findValue(content, CD_TYPE_PATTEN, 'str')].every(elem => elem !== false)))
return false;
switch (type.toUpperCase()){
case 'SINGLE': ret = CD_SINGLE_BASE_CREDIT; break;
case 'DRAMA': ret = CD_DRAMA_BASE_CREDIT; break;
case 'OST':
case 'ALBUM': ret = CD_ALBUM_OST_BASE_CREDIT; break;
default:
return false;
}
ret *= 1 + scanFactor(scan, CD_SCAN_LIMITS, CD_SCAN_FACTORS) + tokuten * CD_TOKUTEN_FACTOR;
break;
case '周边':
case 'EXTRA':
if(!([scan = findValue(content, EXTRA_SCAN_PATTEN),
tokuten = findValue(content, EXTRA_TOKUTEN_PATTEN)].every(elem => elem !== false)))
return false;
scan = scanFactor(scan, EXTRA_SCAN_LIMITS, EXTRA_SCAN_FACTORS);
ret = EXTRA_BASE_CREDIT * (1 + scan + EXTRA_TOKUTEN_FACTOR * tokuten);
break;
default : return false;
}
return ret * D * (time > 0.5 ? 2 / (1 + Math.exp(time - 0.5)) : 1);
};
$.get('httpapi_globalconstant.php?constant=D', function(obj) {
D = parseFloat(obj.data);
}).fail(function() {
alert('Failed to get D.');
}).done(function() {
$(POST_SELECTOR).each(function(index, elem) {
var tid, content = $(elem).children(POST_TO_CONTENT_SELECTOR).html();
if(!POST_PATTEN.test(content))
return;
else if($(elem).prevAll("div").length !== 0)
return;
else if(!(tid = content.match(TORRENT_ID_PATTEN)))
return;
var pid = $(elem).attr('id').match(POST_ID_PATTEN)[1];
$(elem).append(CHECK_AREA_HTML.replace(TO_BE_REPLACED, pid));
$(".UCRewardCalc[data='" + pid + "']").click(function() {
$(this).attr('disabled', true);
var myThis = $(this), dt, complete = $(this).prevAll('.UCRewardComplete').is(':checked'), dupe = $(this).prevAll('.UCRewardDupe').is(':checked');
$.get('httpapi_torrentinfo.php?tid=' + tid[1], function(obj) {
dt = ((Date.now() / 1000 - obj.data.added) / (86400 * 365)).toFixed(3); //year
}).done(function (){
var msg, amount = doCalc(content, complete, dupe, dt);
if(!amount) {
myThis.attr('value', '非法格式');
return;
}
amount = Math.floor(amount);
myThis.attr('value', '奖励' + amount + 'UCoin').attr('disabled', false);
msg = 'tid: ' + tid[1] + ', D = ' + D.toFixed(3) + ', ' + dt + ' years' + (complete ? ', complete' : '') + (dupe ? ', dupe' : '');
myThis.unbind('click').click(function() {
$(this).attr('disabled', true);
$.ajax({
url: 'forumpostadmin.php',
method: 'post',
tPid: pid,
data: 'markdes=add&mark=' + amount + '&reason=' + msg + '&admintype=mark&pid=' + pid
}).fail(function() {
alert('Failed on post#' + this.tPid);
}).done(function() {
location.reload();
});
});
});
});
});
});
})();