Vote counter userscript

From BlogNomic Wiki
Revision as of 20:20, 15 September 2020 by Card (talk | contribs) (Created page with "=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 rul...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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.

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();
       }
     });