Compare commits
30 commits
schupfed-c
...
main
Author | SHA1 | Date | |
---|---|---|---|
fbf28302b2 | |||
23bf7d7cec | |||
4036bdc042 | |||
a8f909e7e4 | |||
f8137f3664 | |||
ac9fdb9f35 | |||
d9435633a7 | |||
13aca8e5c7 | |||
1e87966dd7 | |||
19fa4454a1 | |||
23c26422e6 | |||
2d2843f128 | |||
e50d3108eb | |||
91b3c533c3 | |||
9737674953 | |||
7513837bb8 | |||
cd7baddc87 | |||
3a785dd858 | |||
af3dd704e9 | |||
0d4542f133 | |||
b1693bffe6 | |||
014f3c15d3 | |||
b8fbb4027a | |||
c002ca3451 | |||
011d7b3fb1 | |||
1da4f5ae36 | |||
2a9d53fe53 | |||
dfcf6af304 | |||
2e3c9eb117 | |||
4c731d3984 |
2 changed files with 414 additions and 54 deletions
14
README.md
14
README.md
|
@ -3,24 +3,26 @@
|
||||||
This is a [greasemonkey](https://github.com/greasemonkey/greasemonkey) userscript for [onlinetichu.com](onlinetichu.com) to count cards.
|
This is a [greasemonkey](https://github.com/greasemonkey/greasemonkey) userscript for [onlinetichu.com](onlinetichu.com) to count cards.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
All of these can be toggled individually via buttons after activating the extension via the counter on the top right
|
||||||
- Keeps track all cards played:
|
- Keeps track all cards played:
|
||||||
- Toggle display of cards with button
|
- Toggle display of cards with button
|
||||||
- Toggle between remaining / played cards
|
- Toggle between remaining / played cards
|
||||||
- Disable and remove 'Auto Fold' functionality, which leaks information
|
- Disable and remove `Auto Fold`
|
||||||
- Replaced with a 'Smart Fold' functionality, which automatically folds iff
|
- Replaced with a 'Smart Fold' functionality, which automatically folds iff
|
||||||
- the player has less than 4 cards remaining
|
- the player has less than 4 cards remaining
|
||||||
- the current combination consists of more card than the player has on their hand
|
- the current combination consists of more card than the player has on their hand
|
||||||
|
- `autoWish`:
|
||||||
|
- automatically selects (as a default) the value of the card which you gave to the player of your right
|
||||||
|
- in case of a dog selects an ace as default
|
||||||
|
- `davidProtection`:
|
||||||
|
- warns you on folding when you have cards selected
|
||||||
|
- fold a second time to actually fold in this case
|
||||||
|
|
||||||
Possibly more in the future
|
Possibly more in the future
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
- qutebrowser: just copy this userscript into the `greasemonkey` monkey folder in your qute config directory
|
- qutebrowser: just copy this userscript into the `greasemonkey` monkey folder in your qute config directory
|
||||||
Usually, this is `.config/qutebrowser/greasemonkey`.
|
Usually, this is `.config/qutebrowser/greasemonkey`.
|
||||||
- Firefox: Install the [greasemonkey](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/) add-on.
|
|
||||||
Now you have to visit a website where this script is hosted with a `.user.js` extension.
|
|
||||||
Unfortunately, I found no better way of installing user scripts to greasemonkey
|
|
||||||
The latest (or at least a) release (read: version that is not obviously broken) is available at
|
|
||||||
https://maximilian-kessler.de/files/greasemonkey/onlinetichu-counter.user.js
|
|
||||||
|
|
||||||
On visiting [onlinetichu.com](onlinetichu.com), you should now automatically have the corresponding buttons and functionality
|
On visiting [onlinetichu.com](onlinetichu.com), you should now automatically have the corresponding buttons and functionality
|
||||||
available in the upper status bar.
|
available in the upper status bar.
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name onlinetichu.com card counter
|
// @name onlinetichu.com card counter
|
||||||
// @version 1.0.2
|
// @version 1.4.0
|
||||||
// @description automatically count cards at onlinetichu.com
|
// @description automatically count cards at onlinetichu.com
|
||||||
// @author kesslermaximilian
|
|
||||||
// @match *://*.onlinetichu.com/Site/Game/Table/*
|
// @match *://*.onlinetichu.com/Site/Game/Table/*
|
||||||
|
// @author Maximilian Keßler
|
||||||
|
// @namespace https://gitlab.com/kesslermaximilian/onlinetichu-counter
|
||||||
|
// @license MIT
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
// disable auto fold functionality completely
|
// disable auto fold functionality completely
|
||||||
|
@ -16,18 +18,52 @@ function injectCounter() {
|
||||||
var myStyles = `
|
var myStyles = `
|
||||||
#playedHigh {
|
#playedHigh {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 620px;
|
top: 45px;
|
||||||
width: 850px;
|
left: 5px;
|
||||||
|
width: 935px;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#playedLow {
|
#playedLow {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 750px;
|
top: 170px;
|
||||||
width: 850px;
|
left: 5px;
|
||||||
|
width: 935px;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#counterField {
|
||||||
|
position: absolute;
|
||||||
|
width: 945px;
|
||||||
|
height: 300px;
|
||||||
|
top: 635px;
|
||||||
|
border: 1px solid black;
|
||||||
|
box-shadow: 1px 1px 1px #555;
|
||||||
|
background: #88CC00;
|
||||||
|
}
|
||||||
|
|
||||||
|
#controlBar {
|
||||||
|
position: absolute;
|
||||||
|
min-height: 32px;
|
||||||
|
width: 925px;
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#controlButtonsLeft {
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#controlButtonsRight {
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.playedCardsLayout {
|
.playedCardsLayout {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 125px;
|
height: 125px;
|
||||||
|
@ -54,6 +90,60 @@ function injectCounter() {
|
||||||
console.log(styleSheet);
|
console.log(styleSheet);
|
||||||
document.head.appendChild(styleSheet);
|
document.head.appendChild(styleSheet);
|
||||||
|
|
||||||
|
var controlBar = document.createElement('div');
|
||||||
|
controlBar.id = 'controlBar';
|
||||||
|
|
||||||
|
var controlButtonsLeft = document.createElement('div');
|
||||||
|
controlButtonsLeft.className = 'btn-group';
|
||||||
|
controlButtonsLeft.id = 'controlButtonsLeft';
|
||||||
|
|
||||||
|
var controlButtonsRight = document.createElement('div');
|
||||||
|
controlButtonsRight.className = 'btn-group';
|
||||||
|
controlButtonsRight.id = 'controlButtonsRight';
|
||||||
|
|
||||||
|
var davidProtectionButton = document.createElement('button');
|
||||||
|
davidProtectionButton.className = "btn btn-success btn-xs";
|
||||||
|
davidProtectionButton.id = "davidProtection";
|
||||||
|
davidProtectionButton.type = "button";
|
||||||
|
davidProtectionButton.innerHTML = 'David protection: <span id="davidProtectionValue" data-on="On" data-off="Off">Off</span>';
|
||||||
|
|
||||||
|
var autoWishButton = document.createElement('button');
|
||||||
|
autoWishButton.className = "btn btn-info btn-xs";
|
||||||
|
autoWishButton.id = "autoWish";
|
||||||
|
autoWishButton.type = "button";
|
||||||
|
autoWishButton.innerHTML = 'Auto Wish: <span id="autoWishValue" data-on="On" data-off="Off">Off</span>';
|
||||||
|
|
||||||
|
var showRemainingButton = document.createElement('button');
|
||||||
|
showRemainingButton.className = "btn btn-info btn-xs";
|
||||||
|
showRemainingButton.id = "showRemaining";
|
||||||
|
showRemainingButton.type = "button";
|
||||||
|
showRemainingButton.innerHTML = 'Show: <span id="showRemainingValue" data-on="Remaining" data-off="Played">Remaining</span>';
|
||||||
|
|
||||||
|
var showOwnCardsButton = document.createElement('button');
|
||||||
|
showOwnCardsButton.className = "btn btn-primary btn-xs";
|
||||||
|
showOwnCardsButton.id = "showOwnCards";
|
||||||
|
showOwnCardsButton.type = "button";
|
||||||
|
showOwnCardsButton.innerHTML = 'OwnCards: <span id="showOwnCardsValue" data-on="Shown" data-off="Hidden">Shown</span>';
|
||||||
|
|
||||||
|
var showCountedCardsButton = document.createElement('button');
|
||||||
|
showCountedCardsButton.className = "btn btn-success btn-xs";
|
||||||
|
showCountedCardsButton.id = "showCountedCards";
|
||||||
|
showCountedCardsButton.type = "button";
|
||||||
|
showCountedCardsButton.innerHTML = 'Show cards: <span id="showCountedCardsValue" data-on="Yes" data-off="No">No</span>';
|
||||||
|
|
||||||
|
controlButtonsRight.appendChild(showOwnCardsButton);
|
||||||
|
controlButtonsRight.appendChild(showRemainingButton);
|
||||||
|
controlButtonsRight.appendChild(showCountedCardsButton);
|
||||||
|
controlButtonsLeft.appendChild(davidProtectionButton);
|
||||||
|
controlButtonsLeft.appendChild(autoWishButton);
|
||||||
|
|
||||||
|
controlBar.appendChild(controlButtonsLeft);
|
||||||
|
controlBar.appendChild(controlButtonsRight);
|
||||||
|
|
||||||
|
var counterField = document.createElement("div");
|
||||||
|
counterField.id = 'counterField';
|
||||||
|
counterField.appendChild(controlBar);
|
||||||
|
|
||||||
// add an extra field where we will put down the played cards
|
// add an extra field where we will put down the played cards
|
||||||
var cardsField = document.createElement('div');
|
var cardsField = document.createElement('div');
|
||||||
cardsField.id = 'cardsField';
|
cardsField.id = 'cardsField';
|
||||||
|
@ -71,9 +161,11 @@ function injectCounter() {
|
||||||
playedLow.className = 'row';
|
playedLow.className = 'row';
|
||||||
playedLow.hidden = true;
|
playedLow.hidden = true;
|
||||||
|
|
||||||
|
counterField.appendChild(playedHigh);
|
||||||
|
counterField.appendChild(playedLow);
|
||||||
|
|
||||||
tableIG = document.getElementById('gameField').parentNode;
|
tableIG = document.getElementById('gameField').parentNode;
|
||||||
tableIG.appendChild(playedHigh);
|
tableIG.appendChild(counterField);
|
||||||
tableIG.appendChild(playedLow);
|
|
||||||
|
|
||||||
var createCardPlace = function(value, shift, node) {
|
var createCardPlace = function(value, shift, node) {
|
||||||
var playedCards = document.createElement('ul');
|
var playedCards = document.createElement('ul');
|
||||||
|
@ -83,7 +175,7 @@ function injectCounter() {
|
||||||
playedCards.className = 'playedCardsLayout list-unstyled';
|
playedCards.className = 'playedCardsLayout list-unstyled';
|
||||||
playedCards.style.width = '160px';
|
playedCards.style.width = '160px';
|
||||||
playedCards.style.marginLeft = '25px';
|
playedCards.style.marginLeft = '25px';
|
||||||
playedCards.style.left = shift*129 + 'px';
|
playedCards.style.left = shift*127 + 'px';
|
||||||
|
|
||||||
node.appendChild(playedCards);
|
node.appendChild(playedCards);
|
||||||
}
|
}
|
||||||
|
@ -102,25 +194,44 @@ function injectCounter() {
|
||||||
smartFoldButton.className = "btn btn-danger btn-xs";
|
smartFoldButton.className = "btn btn-danger btn-xs";
|
||||||
smartFoldButton.id = "smartFold";
|
smartFoldButton.id = "smartFold";
|
||||||
smartFoldButton.type = "button";
|
smartFoldButton.type = "button";
|
||||||
smartFoldButton.innerHTML = 'Smart fold: <span id="smartFoldValue" data-on="Yes" data-off="No">Yes</span>';
|
smartFoldButton.innerHTML = 'Smart fold: <span id="smartFoldValue" data-on="On" data-off="Off">Off</span>';
|
||||||
|
|
||||||
var showPlayedButton = document.createElement('button');
|
var showCardCounterButton = document.createElement('button');
|
||||||
showPlayedButton.className = "btn btn-primary btn-xs";
|
showCardCounterButton.className = "btn btn-primary btn-xs";
|
||||||
showPlayedButton.id = "showPlayed";
|
showCardCounterButton.id = "showCardCounter";
|
||||||
showPlayedButton.type = "button";
|
showCardCounterButton.type = "button";
|
||||||
showPlayedButton.innerHTML = 'Show counted cards: <span id="showPlayedValue" data-on="Yes" data-off="No">No</span>';
|
showCardCounterButton.innerHTML = 'Card Counter: <span id="showCardCounterValue" data-on="On" data-off="Off">No</span>';
|
||||||
|
|
||||||
var showRemainingButton = document.createElement('button');
|
|
||||||
showRemainingButton.className = "btn btn-info btn-xs";
|
|
||||||
showRemainingButton.id = "showRemaining";
|
|
||||||
showRemainingButton.type = "button";
|
|
||||||
showRemainingButton.innerHTML = 'Show: <span id="showRemainingValue" data-on="Remaining" data-off="Played">Remaining</span>';
|
|
||||||
|
|
||||||
buttons = document.getElementById('statusButtons');
|
buttons = document.getElementById('statusButtons');
|
||||||
buttons.insertBefore(showRemainingButton, document.getElementById('autoFold'));
|
buttons.insertBefore(showCardCounterButton, document.getElementById('autoFold'));
|
||||||
buttons.insertBefore(showPlayedButton, document.getElementById('autoFold'));
|
|
||||||
buttons.insertBefore(smartFoldButton, document.getElementById('autoFold'));
|
buttons.insertBefore(smartFoldButton, document.getElementById('autoFold'));
|
||||||
|
|
||||||
|
var patchPlayerStats = function(direction) {
|
||||||
|
playerLevel = document.getElementById(direction + 'PlayerLevel');
|
||||||
|
playerGoldTourns = document.getElementById(direction + 'PlayerGoldTourns');
|
||||||
|
playerTichu = document.getElementById(direction + 'PlayerTichu');
|
||||||
|
playerDiv = playerLevel.parentElement;
|
||||||
|
|
||||||
|
playerDiv.removeChild(playerLevel);
|
||||||
|
playerDiv.removeChild(playerGoldTourns);
|
||||||
|
|
||||||
|
playerMyLevel = document.createElement('div');
|
||||||
|
playerMyLevel.id = direction + 'PlayerMyLevel';
|
||||||
|
playerMyLevel.innerText = '';
|
||||||
|
|
||||||
|
playerTichuCoefficient = document.createElement('div');
|
||||||
|
playerTichuCoefficient.id = direction + 'PlayerTichuCoefficient';
|
||||||
|
playerTichuCoefficient.innerText = '';
|
||||||
|
|
||||||
|
playerDiv.insertBefore(playerMyLevel, playerTichu);
|
||||||
|
playerDiv.insertBefore(playerTichuCoefficient, playerTichu);
|
||||||
|
}
|
||||||
|
|
||||||
|
patchPlayerStats('south');
|
||||||
|
patchPlayerStats('north');
|
||||||
|
patchPlayerStats('east');
|
||||||
|
patchPlayerStats('west');
|
||||||
|
|
||||||
// playedCards.
|
// playedCards.
|
||||||
// ot.$gameField.insertAfter(playedCards, ot.$gameField.lastChild);
|
// ot.$gameField.insertAfter(playedCards, ot.$gameField.lastChild);
|
||||||
|
|
||||||
|
@ -129,22 +240,58 @@ function injectCounter() {
|
||||||
$playedCards: {},
|
$playedCards: {},
|
||||||
$smartFold: $('#smartFold'),
|
$smartFold: $('#smartFold'),
|
||||||
$smartFoldValue: $('#smartFoldValue'),
|
$smartFoldValue: $('#smartFoldValue'),
|
||||||
$showPlayed: $('#showPlayed'),
|
$showCardCounter: $('#showCardCounter'),
|
||||||
$showPlayedValue: $('#showPlayedValue'),
|
$showCardCounterValue: $('#showCardCounterValue'),
|
||||||
$showRemaining: $('#showRemaining'),
|
$showRemaining: $('#showRemaining'),
|
||||||
$showRemainingValue: $('#showRemainingValue'),
|
$showRemainingValue: $('#showRemainingValue'),
|
||||||
|
$showOwnCards: $('#showOwnCards'),
|
||||||
|
$showOwnCardsValue: $('#showOwnCardsValue'),
|
||||||
|
$showCountedCards: $('#showCountedCards'),
|
||||||
|
$showCountedCardsValue: $('#showCountedCardsValue'),
|
||||||
|
$davidProtection: $('#davidProtection'),
|
||||||
|
$autoWishValue: $('#autoWishValue'),
|
||||||
|
$autoWish: $('#autoWish'),
|
||||||
|
$davidProtectionValue: $('#davidProtectionValue'),
|
||||||
$playedHigh: $('#playedHigh'),
|
$playedHigh: $('#playedHigh'),
|
||||||
$playedLow: $('#playedLow'),
|
$playedLow: $('#playedLow'),
|
||||||
|
$counterField: $('#counterField'),
|
||||||
|
$playerMyLevel: {
|
||||||
|
'east': $('#eastPlayerMyLevel'),
|
||||||
|
'north': $('#northPlayerMyLevel'),
|
||||||
|
'west': $('#westPlayerMyLevel'),
|
||||||
|
'south': $('#southPlayerMyLevel'),
|
||||||
|
},
|
||||||
|
$playerTichuCoefficient: {
|
||||||
|
'east': $('#eastPlayerTichuCoefficient'),
|
||||||
|
'north': $('#northPlayerTichuCoefficient'),
|
||||||
|
'west': $('#westPlayerTichuCoefficient'),
|
||||||
|
'south': $('#southPlayerTichuCoefficient'),
|
||||||
|
},
|
||||||
|
|
||||||
|
// dynamic game state
|
||||||
allCards: {},
|
allCards: {},
|
||||||
playedCards: {},
|
playedCards: {},
|
||||||
totalPlayed: [],
|
totalPlayed: [],
|
||||||
exchangedTo: {},
|
exchangedTo: {},
|
||||||
exchangedFrom: {},
|
exchangedFrom: {},
|
||||||
smartFold: true,
|
handCardShuffle: [],
|
||||||
showPlayed: false,
|
playerNames: {},
|
||||||
|
ownCards: [],
|
||||||
|
|
||||||
|
// config values, triggered with buttons
|
||||||
|
smartFold: false,
|
||||||
|
showCardCounter: false,
|
||||||
|
showOwnCards: true,
|
||||||
showRemaining: true,
|
showRemaining: true,
|
||||||
bombAfterFold: null,
|
showCountedCards: false,
|
||||||
|
davidProtection: false,
|
||||||
|
autoWish: false,
|
||||||
|
shuffleCards: true,
|
||||||
|
|
||||||
|
// dynamic feature state
|
||||||
|
davidProtectionTriggered: true,
|
||||||
|
bombAfterFold: null, // to implement
|
||||||
|
stats: {},
|
||||||
|
|
||||||
util: {
|
util: {
|
||||||
displayCardsHtmlString: function(cards) {
|
displayCardsHtmlString: function(cards) {
|
||||||
|
@ -188,11 +335,106 @@ function injectCounter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contained;
|
return contained;
|
||||||
|
},
|
||||||
|
|
||||||
|
extractInt: function(text) {
|
||||||
|
num = /\d+(m|k)?/.exec(text)[0];
|
||||||
|
if (num.includes('k')) {
|
||||||
|
return 1000 * parseInt(num.split('k')[0]);
|
||||||
|
} else if (num.includes('m')) {
|
||||||
|
return 1000000 * parseInt(num.split('m')[0]);
|
||||||
|
}
|
||||||
|
return parseInt(num);
|
||||||
|
},
|
||||||
|
|
||||||
|
extractFloat: function(text) {
|
||||||
|
num = /\d+(\.\d+)?/.exec(text)[0];
|
||||||
|
return parseFloat(num);
|
||||||
|
},
|
||||||
|
|
||||||
|
// warning: note that this is async
|
||||||
|
getStats: function(user) {
|
||||||
|
$.get('https://www.onlinetichu.com/Site/Profiles/User/' + user, null, function(text){
|
||||||
|
statsNav = $(text).find('#nav-statistics');
|
||||||
|
wbox1 = statsNav.children()[1];
|
||||||
|
|
||||||
|
c1 = wbox1.children[0].children[0].children[1].children;
|
||||||
|
c2 = wbox1.children[0].children[0].children[2].children;
|
||||||
|
|
||||||
|
|
||||||
|
var generalStats = {
|
||||||
|
level: otc.util.extractInt( c1[0].innerText),
|
||||||
|
nextLevelIn: otc.util.extractFloat( c1[1].innerText),
|
||||||
|
rating: otc.util.extractInt( c1[2].innerText),
|
||||||
|
games: otc.util.extractFloat( c1[3].innerText),
|
||||||
|
wins: otc.util.extractFloat( c1[4].innerText.split("-")[0]),
|
||||||
|
defeats: otc.util.extractFloat( c1[4].innerText.split("-")[1]),
|
||||||
|
winningPercentage: (otc.util.extractFloat( c1[5].innerText)).toFixed(1),
|
||||||
|
goldGames: otc.util.extractFloat( c1[6].innerText),
|
||||||
|
goldWins: otc.util.extractFloat( c1[7].innerText.split("-")[0]),
|
||||||
|
goldDefeats: otc.util.extractFloat( c1[7].innerText.split("-")[1]),
|
||||||
|
goldWinningPercentage: otc.util.extractFloat( c1[8].innerText),
|
||||||
|
points: otc.util.extractInt( c1[9].innerText),
|
||||||
|
rounds: otc.util.extractInt( c1[10].innerText),
|
||||||
|
oneTwo: otc.util.extractInt( c1[11].innerText),
|
||||||
|
grandTichuPercentage: otc.util.extractFloat( c2[0].innerText),
|
||||||
|
grandTichuCalled: otc.util.extractInt( c2[1].innerText),
|
||||||
|
grandTichuSuccessful: otc.util.extractInt( c2[2].innerText),
|
||||||
|
tichuPercentage: otc.util.extractFloat( c2[3].innerText),
|
||||||
|
tichuCalled: otc.util.extractInt( c2[4].innerText),
|
||||||
|
tichuSuccessful: otc.util.extractInt( c2[5].innerText),
|
||||||
|
tournaments: otc.util.extractInt( c2[6].innerText),
|
||||||
|
tournamentsFirstAward: otc.util.extractInt( c2[7].innerText),
|
||||||
|
tournamentsSecondAward: otc.util.extractInt( c2[8].innerText),
|
||||||
|
abandonments: otc.util.extractInt( c2[9].innerText)
|
||||||
|
};
|
||||||
|
|
||||||
|
lostGrand = generalStats.grandTichuCalled - generalStats.grandTichuSuccessful;
|
||||||
|
lostTichu = generalStats.tichuCalled - generalStats.tichuSuccessful;
|
||||||
|
|
||||||
|
var customStats = {
|
||||||
|
abandonmentRate: (generalStats.abandonments / (generalStats.games + generalStats.goldGames) * 100).toFixed(1),
|
||||||
|
grandTichuUnsuccesful: lostGrand,
|
||||||
|
tichuUnsuccesful: lostTichu,
|
||||||
|
tichuCoefficient: (( (generalStats.grandTichuSuccessful - lostGrand) * 200 + (generalStats.tichuSuccessful - lostTichu) * 100 ) / generalStats.rounds).toFixed(1),
|
||||||
|
oneTwoCoefficient: (100 * generalStats.oneTwo / generalStats.rounds).toFixed(1) // note that we only use 100 here, as a One-Two is scored for both players. This way, this is better comparable to the tichuCoefficient
|
||||||
|
}
|
||||||
|
|
||||||
|
var userStats = {
|
||||||
|
custom: customStats,
|
||||||
|
general: generalStats
|
||||||
|
}
|
||||||
|
|
||||||
|
otc.stats[user] = userStats ;
|
||||||
|
// console.log('Fetched stats of user ' + user);
|
||||||
|
|
||||||
|
// update stats shown at table
|
||||||
|
otc.action.updateDisplayStats();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
action: {
|
action: {
|
||||||
|
|
||||||
|
selectAutoWish: function() {
|
||||||
|
if (otc.exchangedTo['east'] == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val = 0;
|
||||||
|
if (otc.exchangedTo['east'].Shape < 4 ) {
|
||||||
|
val = otc.exchangedTo['east'].Value;
|
||||||
|
} else if (otc.exchangedTo['east'].Shape == 5) {
|
||||||
|
val = 14; // wish for ace by default if we gave a dog to the right
|
||||||
|
}
|
||||||
|
button = document.getElementById("askCard_" + val);
|
||||||
|
button.click();
|
||||||
|
},
|
||||||
|
|
||||||
|
deSelectAutoWish: function() {
|
||||||
|
button = document.getElementById("askCard_0");
|
||||||
|
button.click();
|
||||||
|
},
|
||||||
|
|
||||||
handlePlayedCard: function(card) {
|
handlePlayedCard: function(card) {
|
||||||
index = 0;
|
index = 0;
|
||||||
// special cards have Shapes 4,5,6,7. We group them at value 1
|
// special cards have Shapes 4,5,6,7. We group them at value 1
|
||||||
|
@ -225,11 +467,19 @@ function injectCounter() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
resetPlayedCards: function() {
|
reset: function() {
|
||||||
for(let i = 1; i < 15; i++) {
|
for(let i = 1; i < 15; i++) {
|
||||||
otc.playedCards[i] = [];
|
otc.playedCards[i] = [];
|
||||||
}
|
}
|
||||||
|
dirs = ['east', 'north', 'west'];
|
||||||
|
for (i in dirs) {
|
||||||
|
otc.exchangedTo[dirs[i]] = null;
|
||||||
|
otc.exchangedFrom[dirs[i]] = null;
|
||||||
|
}
|
||||||
otc.totalPlayed = [];
|
otc.totalPlayed = [];
|
||||||
|
otc.handCardShuffle = [];
|
||||||
|
otc.playerNames = {};
|
||||||
|
otc.stats = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
drawPlayedCards: function() {
|
drawPlayedCards: function() {
|
||||||
|
@ -237,7 +487,7 @@ function injectCounter() {
|
||||||
if (otc.showRemaining) {
|
if (otc.showRemaining) {
|
||||||
cards = [];
|
cards = [];
|
||||||
for(let j=0; j < otc.allCards[i].length; j ++) {
|
for(let j=0; j < otc.allCards[i].length; j ++) {
|
||||||
if(!otc.util.cardInArray(otc.allCards[i][j], otc.playedCards[i])) {
|
if(!otc.util.cardInArray(otc.allCards[i][j], otc.playedCards[i]) && (otc.showOwnCards || !otc.util.cardInArray(otc.allCards[i][j], otc.ownCards))) {
|
||||||
cards.push(otc.allCards[i][j]);
|
cards.push(otc.allCards[i][j]);
|
||||||
}
|
}
|
||||||
otc.$playedCards[i].html(otc.util.displayCardsHtmlString(cards));
|
otc.$playedCards[i].html(otc.util.displayCardsHtmlString(cards));
|
||||||
|
@ -246,6 +496,24 @@ function injectCounter() {
|
||||||
otc.$playedCards[i].html(otc.util.displayCardsHtmlString(otc.playedCards[i]));
|
otc.$playedCards[i].html(otc.util.displayCardsHtmlString(otc.playedCards[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateDisplayStats: function() {
|
||||||
|
dirs = ['east', 'north', 'south', 'west'];
|
||||||
|
for(i in dirs) {
|
||||||
|
stats = otc.stats[otc.playerNames[dirs[i]]];
|
||||||
|
if (stats != undefined) {
|
||||||
|
t = 'L' + stats.general.level + ' A' + stats.custom.abandonmentRate + ' W' + stats.general.winningPercentage + '';
|
||||||
|
otc.$playerMyLevel[dirs[i]].text(t);
|
||||||
|
|
||||||
|
t = 'T' + stats.custom.tichuCoefficient + ' O' + stats.custom.oneTwoCoefficient;
|
||||||
|
otc.$playerTichuCoefficient[dirs[i]].text(t);
|
||||||
|
} else {
|
||||||
|
otc.$playerMyLevel[dirs[i]].text('');
|
||||||
|
otc.$playerTichuCoefficient[dirs[i]].text('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log('updated shown stats');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,7 +522,7 @@ function injectCounter() {
|
||||||
window.otc = OnlineTichuCounter;
|
window.otc = OnlineTichuCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
otc.$showRemaining.hide();
|
otc.$counterField.hide();
|
||||||
|
|
||||||
// add functionality to smartFold button
|
// add functionality to smartFold button
|
||||||
otc.$smartFold.click(function () {
|
otc.$smartFold.click(function () {
|
||||||
|
@ -267,18 +535,47 @@ function injectCounter() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// add functionality to show button
|
// add functionality to show button
|
||||||
otc.$showPlayed.click(function () {
|
otc.$showCardCounter.click(function () {
|
||||||
otc.showPlayed = !otc.showPlayed;
|
otc.showCardCounter = !otc.showCardCounter;
|
||||||
if (otc.showPlayed) {
|
if (otc.showCardCounter) {
|
||||||
otc.$showPlayedValue.text(otc.$showPlayedValue.data('on'));
|
otc.$showCardCounterValue.text(otc.$showCardCounterValue.data('on'));
|
||||||
|
otc.$counterField.show();
|
||||||
|
} else {
|
||||||
|
otc.$showCardCounterValue.text(otc.$showCardCounterValue.data('off'));
|
||||||
|
otc.$counterField.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
otc.$showCountedCards.click(function () {
|
||||||
|
otc.showCountedCards = !otc.showCountedCards;
|
||||||
|
if (otc.showCountedCards) {
|
||||||
|
otc.$showCountedCardsValue.text(otc.$showCountedCardsValue.data('on'));
|
||||||
otc.$playedHigh.show();
|
otc.$playedHigh.show();
|
||||||
otc.$playedLow.show();
|
otc.$playedLow.show();
|
||||||
otc.$showRemaining.show();
|
|
||||||
} else {
|
} else {
|
||||||
otc.$showPlayedValue.text(otc.$showPlayedValue.data('off'));
|
otc.$showCountedCardsValue.text(otc.$showCountedCardsValue.data('off'));
|
||||||
otc.$playedHigh.hide();
|
otc.$playedHigh.hide();
|
||||||
otc.$playedLow.hide();
|
otc.$playedLow.hide();
|
||||||
otc.$showRemaining.hide();
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
otc.$davidProtection.click(function () {
|
||||||
|
otc.davidProtection = !otc.davidProtection;
|
||||||
|
if (otc.davidProtection) {
|
||||||
|
otc.$davidProtectionValue.text(otc.$davidProtectionValue.data('on'));
|
||||||
|
} else {
|
||||||
|
otc.$davidProtectionValue.text(otc.$davidProtectionValue.data('off'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
otc.$autoWish.click(function () {
|
||||||
|
otc.autoWish = !otc.autoWish;
|
||||||
|
if (otc.autoWish) {
|
||||||
|
otc.$autoWishValue.text(otc.$autoWishValue.data('on'));
|
||||||
|
otc.action.selectAutoWish();
|
||||||
|
} else {
|
||||||
|
otc.$autoWishValue.text(otc.$autoWishValue.data('off'));
|
||||||
|
otc.action.deSelectAutoWish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -292,13 +589,40 @@ function injectCounter() {
|
||||||
otc.action.drawPlayedCards();
|
otc.action.drawPlayedCards();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
otc.$showOwnCards.click(function () {
|
||||||
|
otc.showOwnCards = !otc.showOwnCards;
|
||||||
|
if (otc.showOwnCards) {
|
||||||
|
otc.$showOwnCardsValue.text(otc.$showOwnCardsValue.data('on'));
|
||||||
|
} else {
|
||||||
|
otc.$showOwnCardsValue.text(otc.$showOwnCardsValue.data('off'));
|
||||||
|
}
|
||||||
|
otc.action.drawPlayedCards();
|
||||||
|
});
|
||||||
|
|
||||||
for(let i = 1; i < 15; i++) {
|
for(let i = 1; i < 15; i++) {
|
||||||
otc.$playedCards[i] = $('#playedCards' + i);
|
otc.$playedCards[i] = $('#playedCards' + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
otc.action.resetPlayedCards();
|
otc.action.reset();
|
||||||
otc.util.populateAllCards();
|
otc.util.populateAllCards();
|
||||||
|
|
||||||
|
// overwrite functionality of fold button
|
||||||
|
ot.$fold.unbind();
|
||||||
|
ot.$fold.hide().click(function () {
|
||||||
|
if (otc.davidProtection) {
|
||||||
|
if(ot.$passCards().length != 0 && !otc.davidProtectionTriggered) {
|
||||||
|
console.log('david protection triggered');
|
||||||
|
ot.$gameMessage.text("Selected cards detected. Press again to fold!");
|
||||||
|
ot.HorizontalAlign(ot.$gameMessage);
|
||||||
|
otc.davidProtectionTriggered = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ot.action.Fold();
|
||||||
|
otc.davidProtectionTriggered = false;
|
||||||
|
$(this).hide();
|
||||||
|
});
|
||||||
|
|
||||||
MyTableState = (function() {
|
MyTableState = (function() {
|
||||||
var cachedFunction = ot.reaction.TableState;
|
var cachedFunction = ot.reaction.TableState;
|
||||||
|
|
||||||
|
@ -307,12 +631,14 @@ function injectCounter() {
|
||||||
|
|
||||||
message = arguments[0];
|
message = arguments[0];
|
||||||
|
|
||||||
|
// console.log(message);
|
||||||
|
|
||||||
// console.log('detected table state change event');
|
// console.log('detected table state change event');
|
||||||
// console.log(message.Table.Status);
|
// console.log(message.Table.Players);
|
||||||
|
|
||||||
// reset played cards at start of round
|
// reset played cards at start of round
|
||||||
if(message.Table.Status == 'WaitForNextCards') {
|
if(message.Table.Status == 'WaitForNextCards' && otc.totalPlayed.length != 0) {
|
||||||
otc.action.resetPlayedCards();
|
otc.action.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message.Table.Status == 'Playing') {
|
if(message.Table.Status == 'Playing') {
|
||||||
|
@ -321,22 +647,48 @@ function injectCounter() {
|
||||||
|
|
||||||
otc.action.drawPlayedCards();
|
otc.action.drawPlayedCards();
|
||||||
|
|
||||||
console.log('reached smartFold point');
|
// console.log('reached smartFold point');
|
||||||
|
spectator = true;
|
||||||
|
|
||||||
|
// reset player names as they might have changed
|
||||||
|
otc.playerNames = {};
|
||||||
|
|
||||||
|
southPosition = 1;
|
||||||
$(message.Table.Players).each(function () {
|
$(message.Table.Players).each(function () {
|
||||||
if (this.Username == ot.$Username.val()) {
|
if (this.Username == ot.$Username.val()) {
|
||||||
console.log('found player');
|
otc.ownCards = this.Cards;
|
||||||
|
spectator = false;
|
||||||
|
southPosition = this.Position;
|
||||||
|
// console.log('found player');
|
||||||
if (message.Table.Turn == this.Position) {
|
if (message.Table.Turn == this.Position) {
|
||||||
console.log('my turn!');
|
// console.log('my turn!');
|
||||||
if (this.Cards.length < 4 && this.Cards.length < message.Table.TableCards.length) {
|
if (this.Cards.length < 4 && this.Cards.length < message.Table.TableCards.length) {
|
||||||
console.log('obvious that have to fold now');
|
|
||||||
if (otc.smartFold) {
|
if (otc.smartFold) {
|
||||||
|
if(this.MustFold) {
|
||||||
ot.action.Fold();
|
ot.action.Fold();
|
||||||
|
console.log('smart fold activated');
|
||||||
|
} else {
|
||||||
|
console.log('prevented bug by not smartfolding');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get stats of player if we don't have them yet)
|
||||||
|
if (otc.stats[this.Username] === undefined) {
|
||||||
|
otc.util.getStats(this.Username);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(message.Table.Players).each(function () {
|
||||||
|
dirs = ['south', 'east', 'north', 'west'];
|
||||||
|
index = (this.Position - southPosition + 4) % 4;
|
||||||
|
otc.playerNames[dirs[index]] = this.Username;
|
||||||
|
});
|
||||||
|
|
||||||
|
otc.action.updateDisplayStats();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +738,12 @@ function injectCounter() {
|
||||||
|
|
||||||
console.log(otc.exchangedTo);
|
console.log(otc.exchangedTo);
|
||||||
|
|
||||||
|
if(otc.autoWish) {
|
||||||
|
otc.action.selectAutoWish();
|
||||||
|
} else {
|
||||||
|
otc.action.deSelectAutoWish();
|
||||||
|
}
|
||||||
|
|
||||||
var result = cachedFunction.apply(this, arguments);
|
var result = cachedFunction.apply(this, arguments);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +764,7 @@ function injectCounter() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Special care is to be taken to safely inject our javascript into the websiet
|
// Special care is to be taken to safely inject our javascript into the website
|
||||||
// without the website being able to talk back to greasemonkey
|
// without the website being able to talk back to greasemonkey
|
||||||
// (which would be a security problem)
|
// (which would be a security problem)
|
||||||
// see
|
// see
|
||||||
|
|
Loading…
Reference in a new issue