Returning players! Wiki accounts were reset in late 2014. If you haven't played since then and wish to edit the wiki, you'll need a fresh account.

Vote counter userscript

From BlogNomic Wiki
Jump to navigation Jump to search

Preface

this is the BN Greasemonkey Script available under the Useful Links section of the Main Page. i have modified it to count correctly with the current ruleset. the ruleset changed to not allow Deferential votes on non-Proposal votable matters, mainly CfJ. i also added functionality to count if the Imperial Deferentials rule is Active.

note, due to wikimedia formatting, you will need to go into edit mode before copying this script for it to work since media wiki counts two single quotes next to each other as the code for making italics.

Script

   // ==UserScript==
   // @name           BNScript: BlogNomic Utility Script
   // @namespace      blognomic
   // @version        1.17.1.9
   // @description    Utility script for the game of BlogNomic, assisting admin in the automatic counting of votes and flagging of new comments.
   // @include        https://*blognomic.com/
   // @include        https://*blognomic.com/archive/*
   // @include        https://*blognomic.com/blognomic/archive/*
   // @include        https://*blognomic.com/blognomic/
   // @grant          GM_getValue
   // @grant          GM_setValue
   // @grant          GM_log
   // @require        http://code.jquery.com/jquery-1.11.2.min.js
   // ==/UserScript==
   var settings_default = {
     'showNew': true,
     'showTotal': true,
     'debug': false,
     'emperor': ,
     'colorPassed': '#00cc00',
     'colorFailed': '#ff0000',
     'colorNew': '#ff0000'
   };
   var form_data =
     'Show new comments: <input type="checkbox" name="showNew" />
' + 'Show vote totals: <input type="checkbox" name="showTotal" />
' + 'Debug mode: <input type="checkbox" name="debug" />
' + 'Current Emperor: <input type="text" name="emperor" />
' + 'Color of passed counts: <input type="text" name="colorPassed" />
' + 'Color of failed counts: <input type="text" name="colorFailed" />
' + 'Color of new comments: <input type="text" name="colorNew" />
' + '<button type="button">Save</button>';
   inputs = document.getElementsByTagName("input");
   for (i=0; i<inputs.length; ++i) {
     if(inputs[i].name == "notify_me") inputs[i].checked = false;
   }
   // This whole block from http://umkk.eu/wp-content/uploads/2009/10/json.js
   var JSON=JSON||{};(
     function() {
       function f(n) {
         return n<10 ? '0' + n : n;
       }
       if (typeof Date.prototype.toJSON !== 'function') {
         Date.prototype.toJSON = function(key) {
   return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' +
   f(this.getUTCMonth()+1) + '-' + f(this.getUTCDate()) + 'T' +
   f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' +
   f(this.getUTCSeconds()) + 'Z' : null;
         };
         String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function(key) {
   return this.valueOf();
         }
       }
       var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;
       function quote(string) {
         escapable.lastIndex=0;
         return escapable.test(string) ? '"' +
   string.replace(escapable, function(a) {
      var c=meta[a];
      return typeof c === 'string' ? c : '\\u' +
        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
    }) + '"' : '"' + string + '"'
   }
       function str(key,holder) {
         var i, k, v, length, mind=gap, partial, value=holder[key];
         if (value && typeof value === 'object' &&
    typeof value.toJSON === 'function') {
   value=value.toJSON(key);
         }
         if (typeof rep === 'function') {
   value = rep.call(holder,key,value);
         }
         switch (typeof value) {
         case'string':
   return quote(value);
         case'number':
   return isFinite(value) ? String(value) : 'null';
         case'boolean':
         case'null':
   return String(value);
         case'object':
   if(!value) {
    return'null';
   }
   gap += indent;
   partial=[];
   if (Object.prototype.toString.apply(value) === '[object Array]') {
    length=value.length;
    for (i=0; i<length; i+=1) {
      partial[i] = str(i,value) || 'null';
    }
    v = partial.length === 0 ? '[]' : gap ? '[\n' + gap +
      partial.join(',\n' + gap) + '\n' + mind + ']' : '[' +
      partial.join(',') + ']';
    gap = mind;
    return v;
   }
   if (rep && typeof rep === 'object') {
    length = rep.length;
    for(i=0; i<length; i+=1) {
      k=rep[i];
      if(typeof k === 'string') {
        v=str(k,value);
        if (v) {
   partial.push(quote(k) + (gap ? ': ' : ':') + v);
        }
      }
    }
   }
   else {
    for(k in value) {
      if (Object.hasOwnProperty.call(value,k)) {
        v = str(k,value);
        if (v) {
   partial.push(quote(k) + (gap ? ': ' : ':') + v);
        }
      }
    }
   }
   v = partial.length === 0 ? '{}' : gap ? '{\n' + gap +
    partial.join(',\n' + gap) + '\n' + mind + '}' : '{' +
    partial.join(',') + '}';
   gap = mind;
   return v;
         }
       }
       if (typeof JSON.stringify !== 'function') {
         JSON.stringify = function(value,replacer,space) {
   var i;
   gap = ;
   indent = ;
   if (typeof space === 'number') {
    for (i=0; i<space; i+=1) {
      indent+=' ';
    }
   }
   else if (typeof space === 'string') {
    indent = space;
   }
   rep = replacer;
   if (replacer && typeof replacer !== 'function' &&
      (typeof replacer !== 'object' || typeof replacer.length !==
       'number')) {
    throw new Error('JSON.stringify');
   }
   return str(,{:value});
         }
       }
       if (typeof JSON.parse !== 'function') {
         JSON.parse = function(text,reviver) {
   var j;
   function walk(holder,key) {
    var k, v, value=holder[key];
    if (value && typeof value === 'object') {
      for (k in value) {
        if (Object.hasOwnProperty.call(value,k)) {
   v = walk(value,k);
   if (v!==undefined) {
    value[k] = v;
   }
   else {
    delete value[k];
   }
        }
      }
    }
    return reviver.call(holder,key,value);
   }
   cx.lastIndex=0;
   if (cx.test(text)) {
    text=text.replace(cx,function(a) {
        return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
      });
   }
   if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,)))
   {
    j = eval('(' + text + ')');
    return typeof reviver === 'function' ? walk({:j},) : j;
   }
   throw new SyntaxError('JSON.parse');
         }
       }
     }());
   // End borrowed code
   var settings;
   function getComments(text) {
     return parseInt(text.replace(/[^0-9]/g, ))
   }
   function set(k,v) { // hack
     window.setTimeout(function() {
       GM_setValue(k,v)
     }, 0)
   }
   function get(k,v, callback) { // hack
     window.setTimeout(function() {
       callback(GM_getValue(k,v))
     }, 0)
   }
   function mainPage() {
     $("<button type=\"button\">BNScript settings</button>").prependTo("#sidebar2").click(settings_query);
     $("a[title='Comments']").each(function(i) {
       var link = this
       
       get(this.href, false, function(old_comments) {
         var num_comments = getComments(link.text)
         var num_new_comments = num_comments - (old_comments || 0)
         
         if ((!old_comments && num_comments > 0) || num_comments > old_comments) {
           $(link).append(' (' + num_new_comments + ' new)')
         }
         
         $(link).click(function() {
           set(link.href, num_comments)
         })
         
         if (settings['showNew']) {
           if (num_new_comments > 0) {
             $('#header').append('<a href="' + link.href + '" style="color: ' + settings['colorNew'] + '">' + (num_new_comments) + '</a> ')
           } else {
            $('#header').append('0 ')
           }
         }
       })
     })
   }
   function archivePage() {
     $("a[title='Comments']").each(function(i) {
         set(this.href, getComments(this.text));
       });
     var votes = new Object();
     var proposer;
     proposer = $("p[class=post-footer]").children().filter("em").
       children().filter("a").html();
     var isProposal;
     isProposal = /^Proposal\:/.test($("a[class^=blogpostlink]").html());
     var quorum;
     quorum = $("#PlayerList").next().html();
     quorum = /\D*(\d+)\D*(\d+)/.exec(quorum);
     var numPlayers = parseInt(quorum[1]);
     quorum = parseInt(quorum[2]);
     GM_log('Number of players: ' + numPlayers);
     GM_log('Quorum: ' + quorum);
     var failQuorum = quorum - 1 + numPlayers % 2;
     GM_log('Failure quorum: ' + failQuorum);
     $("div[class='comment']").
       each(
         function(i) {
   var comment = this;
   var name = $(comment).children().filter('h3').children().
    filter('a').html();
   var cbody = $(comment).children().filter('div.commentbody');
   if (settings['debug']) {
    GM_log('In vote-counter: voter #' + i + ': ' + name);
   }
   $(cbody).find("img").each(
    function(j) {
   	    var cb = this;
   	    var vote = cb.getAttribute('alt');
        if (settings['debug']) {
   	      GM_log('In vote-counter: vote #' + j + ': ' + 
   		     vote);
      }
               if (vote == 'for' || vote == 'against' ||
                   vote == 'imperial' ||
                   (vote == 'veto' && isProposal && settings[emperor] !=  && name == settings[emperor]))
                 votes[name] = vote;
               else if (settings['debug'])
                 GM_log('Vote not counted');
    });
         });
     var players = {};
     $("#PlayerList > a").each(function(i) {
         players[$(this).text().replace(/\*$/, "")] = true;
     });
     var numFor = 0;
     var numAgainst = 0;
     var numImp = 0;
     var emperor = ;
     var veto = false;
     var sk = false;
     if (votes[proposer] == undefined)
       votes[proposer] = 'for';
     if (settings['debug']) {
       GM_log('In vote-counter: Vote count: ' + JSON.stringify(votes));
       GM_log('In vote-counter: Proposer: ' + proposer);
       GM_log('In vote-counter: isProposal: ' + isProposal);
     }
     for (key in votes) {
       if (!players[key])
         continue;
       if (settings[emperor] !=  && key == settings['emperor'])
         emperor = votes[key];
       if (votes[key] == 'for')
         numFor++;
       if (votes[key] == 'against')
         numAgainst++;
       if (votes[key] == 'imperial')
         numImp++;
     }
     if (isProposal && emperor == 'veto')
       veto = true;
     if (isProposal && (votes[proposer] == 'against')) // previously included " || (votes[proposer] == 'imperial' && emperor == 'against')" but the rule no longer works that way
       sk = true;
     if (settings['debug']) {
       GM_log('In vote-counter: emperor\'s vote: ' + emperor);
       GM_log('In vote-counter: vote numbers: ' + numFor + ' ' +
     numAgainst + ' ' + numImp);
       GM_log('In vote-counter: veto/s-k: ' + veto + '/' + sk);
     }
     
     if (emperor == 'imperial'){
       if (numFor > numAgainst){
         emperor = 'for';
         numFor++;
       } else{
         emperor = 'against';
         numAgainst++;
       }
     }
     
     var foradj = numFor, agadj = numAgainst, impadj = numImp;
     
     if (emperor == 'for') {
       foradj += impadj;
       impadj = 0;
     }
     if (emperor == 'against') {
       agadj += impadj;
       impadj = 0;
     }
     var sstring;
     sstring = "text-align: left";
     if (foradj >= quorum)
       sstring += '; color: ' + settings['colorPassed'];
     if (agadj >= failQuorum || veto || sk)
       sstring += '; color: ' + settings['colorFailed'];
     var pstring;
     if (veto)
       pstring = 'Vetoed; votes: ';
     else if (sk)
       pstring = 'Self-killed; votes: ';
     else
       pstring = 'Votes: ';
     if (emperor !=  && numImp != 0 ) {
       pstring += foradj + '-' + agadj + ' (' + numFor + '-' + numAgainst +
         '-' + numImp +')';
     }
     else {
       pstring += foradj + '-' + agadj +
         (impadj != 0 ? '-' + impadj : ) + '';
     }
     if (settings['showTotal'])
       $("#main2").prepend(pstring);
   }
   function settings_query(event) {
     var dbody = document.body;
     var bgcolor = $(dbody).css("background-color");
     var form;
     GM_log('At start: ' + JSON.stringify(settings));
     $(dbody).empty();
     $(dbody).css("background-color", bgcolor);
     $(dbody).append('<form></form>');
     form = $(dbody).children().filter('form');
     $(form).submit(function () {
         settings_save($(this));
         return false;
       });
     $(form).append(form_data);
     if (settings['showNew'])
       $(form).children().filter('[name=showNew]').attr('checked', 'checked');
     if (settings['showTotal'])
       $(form).children().filter('[name=showTotal]').attr('checked', 'checked');
     if (settings['debug'])
       $(form).children().filter('[name=debug]').attr('checked', 'checked');
     $(form).children().filter('[name=emperor]').
       attr('value', settings['emperor']);
     $(form).children().filter('[name=colorPassed]').
       attr('value', settings['colorPassed']);
     $(form).children().filter('[name=colorFailed]').
       attr('value', settings['colorFailed']);
     $(form).children().filter('[name=colorNew]').
       attr('value', settings['colorNew']);
     $(form).children().filter('button').click(function (event) {
         settings_save($(this).parent());
       });
   }
   function settings_save(form) {
     settings['showNew'] = form.children().filter('[name=showNew]').is(':checked');
     settings['showTotal'] = form.children().filter('[name=showTotal]').is(':checked');
     settings['debug'] = form.children().filter('[name=debug]').is(':checked');
     settings['emperor'] = form.children().filter('[name=emperor]').prop('value');
     settings['colorPassed'] = form.children().filter('[name=colorPassed]').prop('value');
     settings['colorFailed'] = form.children().filter('[name=colorFailed]').prop('value');
     settings['colorNew'] = form.children().filter('[name=colorNew]').prop('value');
     GM_log(JSON.stringify(settings));
     set("settings", JSON.stringify(settings));
     unsafeWindow.location.reload();
   }
         
   var setstr = GM_getValue("settings");
   $(document).ready(function() {
       if (setstr)
         settings = JSON.parse(setstr);
       else
         settings = settings_default;
       if (/^https?:\/\/(www\.)?blognomic.com\/(blognomic\/)?archive\/.*$/.
   test(location.href)) {
         archivePage();
       }
       else if (/^https?:\/\/(www\.)?blognomic.com\/(blognomic\/)?$/.
       test(location.href)) {
         mainPage();
       }
     });