Completely overhauled passcode redemption.

* Show table by default, offer plaintext option for reward copy-pasting
* Use recommendations from https://plus.google.com/115907431535033114848/posts/PVV9j4fTR2m for item plaintext listing
* Break passcode redemption responses and errors into window.REDEEM_* variables
* If an item isn't known, don't simply let it slip into the Aurbis. Log it separately.
* Don't show AP or XM if the passcode didn't give any.
This commit is contained in:
Morgan Jones 2013-04-23 20:21:48 -05:00
parent 99a18444bf
commit 00523fc03d
2 changed files with 86 additions and 78 deletions

View File

@ -1,79 +1,90 @@
// REDEEMING ///////////////////////////////////////////////////////// // REDEEMING /////////////////////////////////////////////////////////
window.REDEEM_RES_LONG = {'RES_SHIELD' : 'Portal Shield',
'EMITTER_A' : 'Resonator',
'EMP_BURSTER' : 'XMP Burster',
'POWER_CUBE' : 'Power Cube'};
window.REDEEM_RES_SHORT = {'RES_SHIELD' : 'S',
'EMITTER_A' : 'R',
'EMP_BURSTER' : 'X',
'POWER_CUBE' : 'C'};
window.REDEEM_ERRORS = {'ALREADY_REDEEMED' : 'The passcode has already been redeemed.',
'ALREADY_REDEEMED_BY_PLAYER' : 'You have already redeemed this passcode.',
'INVALID_PASSCODE' : 'This passcode is invalid.'};
window.REDEEM_STATUSES = {429 : 'You have been rate-limited by the server. Wait a bit and try again.'};
window.handleRedeemResponse = function(data, textStatus, jqXHR) { window.handleRedeemResponse = function(data, textStatus, jqXHR) {
if(data.error) { if (data.error) {
var error = ''; // Errors are now in window.REDEEM_ERRORS.
if(data.error === 'ALREADY_REDEEMED') { var error = window.REDEEM_ERRORS[data.error] || 'There was a problem redeeming the passcode. Try again?';
error = 'The passcode has already been redeemed.';
} else if(data.error === 'ALREADY_REDEEMED_BY_PLAYER') { // Show an alert and add a console log
error = 'You have already redeemed this passcode.';
} else if(data.error === 'INVALID_PASSCODE') {
error = 'This passcode is invalid.';
} else {
error = 'There was a problem redeeming the passcode. Try again?';
}
alert('<strong>' + data.error + '</strong>\n' + error); alert('<strong>' + data.error + '</strong>\n' + error);
console.log(this.passcode + ' => [ERROR] ' + data.error);
} else if(data.result) { } else if(data.result) {
var tblResult = $('<table class="redeem-result" />'); // Successful redemption
tblResult.append($('<tr><th colspan="2">Passcode accepted!</th></tr>')); var payload = {};
var table_result = ['<th colspan="2"><strong>Passcode accepted!</strong></th>'], plain_result = [];
var table = '', plain = '';
if(data.result.apAward) // Get AP, XM, and other static quantities
tblResult.append($('<tr><td>+</td><td>' + data.result.apAward + 'AP</td></tr>')); var scores = [[parseInt(data.result.apAward), 'AP'], [parseInt(data.result.xmAward), 'XM']];
if(data.result.xmAward) for (var i in scores) {
tblResult.append($('<tr><td>+</td><td>' + data.result.xmAward + 'XM</td></tr>')); if (scores[i][0] > 0) {
table_result.push('<td>+</td><td>' + scores[i][0] + ' ' + scores[i][1] + '</td>');
var resonators = {}; plain_result.push(scores[i][0] + ' ' + scores[i][1]);
var bursts = {};
var shields = {};
var cubes = {};
for(var i in data.result.inventoryAward) {
var acquired = data.result.inventoryAward[i][2];
if(acquired.modResource) {
if(acquired.modResource.resourceType === 'RES_SHIELD') {
var rarity = acquired.modResource.rarity.split('_').map(function (i) {return i[0]}).join('');
if(!shields[rarity]) shields[rarity] = 0;
shields[rarity] += 1;
}
} else if(acquired.resourceWithLevels) {
if(acquired.resourceWithLevels.resourceType === 'EMITTER_A') {
var level = acquired.resourceWithLevels.level
if(!resonators[level]) resonators[level] = 0;
resonators[level] += 1;
} else if(acquired.resourceWithLevels.resourceType === 'EMP_BURSTER') {
var level = acquired.resourceWithLevels.level
if(!bursts[level]) bursts[level] = 0;
bursts[level] += 1;
} else if(acquired.resourceWithLevels.resourceType === 'POWER_CUBE') {
var level = acquired.resourceWithLevels.level
if(!cubes[level]) cubes[level] = 0;
cubes[level] += 1;
}
} }
} }
$.each(resonators, function(lvl, count) { // Track frequencies and levels of items
var text = 'Resonator'; for (var i in data.result.inventoryAward) {
if(count >= 2) text += ' ('+count+')'; var acquired = data.result.inventoryAward[i][2], primary, secondary, type;
tblResult.append($('<tr ><td style="color: ' +window.COLORS_LVL[lvl]+ ';">L' +lvl+ '</td><td>' + text + '</td></tr>')); if (acquired.modResource) {
}); primary = acquired.modResource.resourceType;
$.each(bursts, function(lvl, count) { secondary = acquired.modResource.rarity;
var text = 'Xmp Burster'; type = 'mod';
if(count >= 2) text += ' ('+count+')'; } else if (acquired.resourceWithLevels) {
tblResult.append($('<tr ><td style="color: ' +window.COLORS_LVL[lvl]+ ';">L' +lvl+ '</td><td>' + text + '</td></tr>')); primary = acquired.resourceWithLevels.resourceType;
}); secondary = parseInt(acquired.resourceWithLevels.level);
$.each(cubes, function(lvl, count) { type = 'leveled';
var text = 'Power Cube'; }
if(count >= 2) text += ' ('+count+')';
tblResult.append($('<tr ><td style="color: ' +window.COLORS_LVL[lvl]+ ';">L' +lvl+ '</td><td>' + text + '</td></tr>')); payload[primary] = payload[primary] || {};
}); payload[primary][secondary] = payload[primary][secondary] || {};
$.each(shields, function(lvl, count) { payload[primary][secondary].type = payload[primary][secondary].type || type;
var text = 'Portal Shield'; payload[primary][secondary].count = payload[primary][secondary].count || 0;
if(count >= 2) text += ' ('+count+')'; payload[primary][secondary].count += 1;
tblResult.append($('<tr><td>'+lvl+'</td><td>'+text+'</td></tr>')); }
});
alert(tblResult, true); // Build the table and plaintext arrays
var keys = Object.keys(payload).sort();
for (var k in keys) {
var primary = payload[keys[k]], long_name = window.REDEEM_RES_LONG[keys[k]] || keys[k], short_name = window.REDEEM_RES_SHORT[keys[k]] || '?';
var table_array = [], plain_array = [];
for (var secondary in primary) {
var acquired = primary[secondary];
var span_prefix = acquired.type === 'leveled' ? '<span style="color: ' + window.COLORS_LVL[secondary] + ';">' : '<span style="color: ' + window.COLORS_MOD[secondary] + ';">';
var span_infix = acquired.type === 'leveled' ? secondary : secondary.split('_').map(function (i) {return i[0];}).join('');
var span_suffix = '</span>'
table_array.push('<td>' + span_prefix + (acquired.type === 'leveled' ? 'L' : '') + span_infix + span_suffix + '</td><td>' + long_name + ' [' + primary[secondary].count + ']</td>');
plain_array.push(primary[secondary].count + '@' + (acquired.type === 'leveled' ? short_name : '') + span_prefix + span_infix + span_suffix);
}
table_result.push(table_array.join(''));
plain_result.push(plain_array.join('/'));
}
// Add more HTML tags
plain = '<span style="font-family: monospace;">' + plain_result.join('/') + '</span>';
table_result.push('<td style="font-family: monospace;">&gt;&gt;</td><td><a href="javascript:alert(\'' + escape(plain) + '\', true);" style="font-family: monospace;">[plaintext]</a>');
table = '<table class="redeem-result">' + table_result.map(function(a) {return '<tr>' + a + '</tr>';}).join("\n") + '</table>';
// Display formatted versions in a table, plaintext, and the console log
alert(table, true);
console.log(this.passcode + ' => ' + $(plain).text());
} }
} }
@ -81,16 +92,12 @@ window.setupRedeem = function() {
$("#redeem").keypress(function(e) { $("#redeem").keypress(function(e) {
if((e.keyCode ? e.keyCode : e.which) != 13) return; if((e.keyCode ? e.keyCode : e.which) != 13) return;
var data = {passcode: $(this).val()}; var data = {passcode: $(this).val()};
window.postAjax('redeemReward', data, window.handleRedeemResponse, window.postAjax('redeemReward', data, window.handleRedeemResponse,
function(response) { function(response) {
var extra = ''; var extra = ''
if(response && response.status) { if (response.status) {
if(response.status === 429) { extra = (window.REDEEM_STATUSES[response.status] || 'The server indicated an error.') + ' (HTTP ' + response.status + ')';
extra = 'You have been rate-limited by the server. Wait a bit and try again.';
} else {
extra = 'The server indicated an error.';
}
extra += '\nResponse: HTTP <a href="http://httpstatus.es/' + response.status + '" alt="HTTP ' + response.status + '">' + response.status + '</a>.';
} else { } else {
extra = 'No status code was returned.'; extra = 'No status code was returned.';
} }

View File

@ -78,13 +78,14 @@ window.digits = function(d) {
// able arguments: http://api.jquery.com/jQuery.ajax/ // able arguments: http://api.jquery.com/jQuery.ajax/
// error: see above. Additionally it is logged if the request failed. // error: see above. Additionally it is logged if the request failed.
window.postAjax = function(action, data, success, error) { window.postAjax = function(action, data, success, error) {
data = JSON.stringify($.extend({method: 'dashboard.'+action}, data)); var post_data = JSON.stringify($.extend({method: 'dashboard.'+action}, data));
var remove = function(data, textStatus, jqXHR) { window.requests.remove(jqXHR); }; var remove = function(data, textStatus, jqXHR) { window.requests.remove(jqXHR); };
var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); }; var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); };
var result = $.ajax({ var result = $.ajax({
url: '/rpc/dashboard.'+action, url: '/rpc/dashboard.'+action,
type: 'POST', type: 'POST',
data: data, data: post_data,
context: data,
dataType: 'json', dataType: 'json',
success: [remove, success], success: [remove, success],
error: error ? [errCnt, error] : errCnt, error: error ? [errCnt, error] : errCnt,