fix injection in firefox

This commit is contained in:
Maximilian Keßler 2022-09-17 01:22:20 +02:00
parent fc18c6d448
commit 54b59eb438

View file

@ -1,399 +1,421 @@
// ==UserScript== // ==UserScript==
// @name onlinetichu.com card counter // @name onlinetichu.com card counter
// @version 1.0.0 // @version 1.0.2
// @description automatically count cards at onlinetichu.com // @description automatically count cards at onlinetichu.com
// @author kesslermaximilian // @author kesslermaximilian
// @match *://*.onlinetichu.com/Site/Game/Table/* // @match *://*.onlinetichu.com/Site/Game/Table/*
// ==/UserScript== // ==/UserScript==
// disable auto fold functionality completely // disable auto fold functionality completely
if (ot.AutoFold) { function injectCounter() {
ot.$autoFold.click() if (ot.AutoFold) {
ot.$autoFold.hide() ot.$autoFold.click()
} ot.$autoFold.hide()
var myStyles = `
#playedHigh {
position: absolute;
top: 620px;
width: 850px;
height: 120px;
} }
#playedLow { var myStyles = `
position: absolute; #playedHigh {
top: 750px; position: absolute;
width: 850px; top: 620px;
height: 120px; width: 850px;
} height: 120px;
.playedCardsLayout {
position: absolute;
height: 125px;
}
.playedCardsLayout .card {
width: 80px;
height: 120px;
border-radius: 5px;
float: left;
margin-left: -50px;
text-align: left;
} }
.playedCardsLayout .card:hover { #playedLow {
z-index: 1400; position: absolute;
} top: 750px;
` width: 850px;
height: 120px;
var styleSheet = document.createElement("style")
styleSheet.innerText = myStyles;
console.log(styleSheet);
document.head.appendChild(styleSheet);
// add an extra field where we will put down the played cards
var cardsField = document.createElement('div');
cardsField.id = 'cardsField';
cardsField.style.marginLeft = '25px';
var playedHigh = document.createElement('div');
playedHigh.id = 'playedHigh';
playedHigh.style.marginLeft = '25px';
playedHigh.className = 'row';
playedHigh.hidden = true;
var playedLow = document.createElement('div');
playedLow.id = 'playedLow';
playedLow.style.marginLeft = '25px';
playedLow.className = 'row';
playedLow.hidden = true;
tableIG = document.getElementById('gameField').parentNode;
tableIG.appendChild(playedHigh);
tableIG.appendChild(playedLow);
var createCardPlace = function(value, shift, node) {
var playedCards = document.createElement('ul');
playedCards.id = 'playedCards' + value;
// playedCards.className = 'layoutPlayedCards list-unstyled col-lg-2';
// playedCards.className = 'playedCardsLayout list-unstyled';
playedCards.className = 'playedCardsLayout list-unstyled';
playedCards.style.width = '160px';
playedCards.style.marginLeft = '25px';
playedCards.style.left = shift*129 + 'px';
node.appendChild(playedCards);
}
createCardPlace(1, 0, document.getElementById('playedHigh'));
for(let i = 14; i > 8; i--) {
createCardPlace(i, 14 - i + 1, document.getElementById('playedHigh'));
}
for(let i = 8; i > 1; i--) {
createCardPlace(i, 8 - i, document.getElementById('playedLow'));
}
var smartFoldButton = document.createElement('button');
smartFoldButton.className = "btn btn-danger btn-xs";
smartFoldButton.id = "smartFold";
smartFoldButton.type = "button";
smartFoldButton.innerHTML = 'Smart fold: <span id="smartFoldValue" data-on="Yes" data-off="No">Yes</span>';
var showPlayedButton = document.createElement('button');
showPlayedButton.className = "btn btn-primary btn-xs";
showPlayedButton.id = "showPlayed";
showPlayedButton.type = "button";
showPlayedButton.innerHTML = 'Show counted cards: <span id="showPlayedValue" data-on="Yes" data-off="No">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.insertBefore(showRemainingButton, document.getElementById('autoFold'));
buttons.insertBefore(showPlayedButton, document.getElementById('autoFold'));
buttons.insertBefore(smartFoldButton, document.getElementById('autoFold'));
// playedCards.
// ot.$gameField.insertAfter(playedCards, ot.$gameField.lastChild);
// set up counting of played cards
var OnlineTichuCounter = {
$playedCards: {},
$smartFold: $('#smartFold'),
$smartFoldValue: $('#smartFoldValue'),
$showPlayed: $('#showPlayed'),
$showPlayedValue: $('#showPlayedValue'),
$showRemaining: $('#showRemaining'),
$showRemainingValue: $('#showRemainingValue'),
$playedHigh: $('#playedHigh'),
$playedLow: $('#playedLow'),
allCards: {},
playedCards: {},
totalPlayed: [],
exchangedTo: {},
exchangedFrom: {},
smartFold: true,
showPlayed: false,
showRemaining: true,
bombAfterFold: null,
util: {
displayCardsHtmlString: function(cards) {
htmlString = "";
$(cards).each(function () {
var value = this.Value;
if (this.Shape == 7) {
value = 0;
}
htmlString += '<li id="c' + this.Shape + '-' + value
+ '" class="card c' + this.Shape + '-' + value
+ '" data-shape="' + this.Shape + '" data-value="'
+ value + '"></li>';
});
return htmlString;
},
populateAllCards: function() {
for(let val = 2; val < 15; val++) {
otc.allCards[val] = [];
for(let shape = 0; shape < 4; shape++) {
otc.allCards[val].push({
Shape: shape,
Value: val
});
}
}
otc.allCards[1] = [
{ Shape: 4, Value: 1 }, // mahjong
{ Shape: 5, Value: 0 }, // dog
{ Shape: 6, Value: 15}, // dragon
{ Shape: 7, Value: 14 } // phoenix
];
},
cardInArray: function(card, array) {
contained = false;
for(let i = 0; i < array.length; i++) {
if (array[i].Shape == card.Shape && array[i].Value == card.Value) {
contained = true;
}
}
return contained;
} }
},
action: { .playedCardsLayout {
position: absolute;
height: 125px;
}
handlePlayedCard: function(card) { .playedCardsLayout .card {
index = 0; width: 80px;
// special cards have Shapes 4,5,6,7. We group them at value 1 height: 120px;
if(card.Shape >= 4) { border-radius: 5px;
index = 1; float: left;
if (card.Shape == 7) { margin-left: -50px;
// Treat phoenix as if it had value 14 text-align: left;
// This is important for comparisons later }
card.Value = 14;
.playedCardsLayout .card:hover {
z-index: 1400;
} }
} else { `
index = card.Value;
}
otc.playedCards[index].push(card);
otc.totalPlayed.push(card);
otc.playedCards[index].sort(function(c1, c2){ var styleSheet = document.createElement("style")
return c2.Shape - c1.Shape; styleSheet.innerText = myStyles;
}); console.log(styleSheet);
}, document.head.appendChild(styleSheet);
handlePlayedCards: function(cards) { // add an extra field where we will put down the played cards
if (cards.length === 0) { var cardsField = document.createElement('div');
return; cardsField.id = 'cardsField';
} cardsField.style.marginLeft = '25px';
if (!otc.util.cardInArray(cards[0], otc.totalPlayed)) {
$(message.Table.TableCards).each(
(index, card) => otc.action.handlePlayedCard(card)
);
}
},
resetPlayedCards: function() { var playedHigh = document.createElement('div');
for(let i = 1; i < 15; i++) { playedHigh.id = 'playedHigh';
otc.playedCards[i] = []; playedHigh.style.marginLeft = '25px';
} playedHigh.className = 'row';
otc.totalPlayed = []; playedHigh.hidden = true;
},
drawPlayedCards: function() { var playedLow = document.createElement('div');
for(let i = 1; i < 15; i++) { playedLow.id = 'playedLow';
if (otc.showRemaining) { playedLow.style.marginLeft = '25px';
cards = []; playedLow.className = 'row';
for(let j=0; j < otc.allCards[i].length; j ++) { playedLow.hidden = true;
if(!otc.util.cardInArray(otc.allCards[i][j], otc.playedCards[i])) {
cards.push(otc.allCards[i][j]); tableIG = document.getElementById('gameField').parentNode;
tableIG.appendChild(playedHigh);
tableIG.appendChild(playedLow);
var createCardPlace = function(value, shift, node) {
var playedCards = document.createElement('ul');
playedCards.id = 'playedCards' + value;
// playedCards.className = 'layoutPlayedCards list-unstyled col-lg-2';
// playedCards.className = 'playedCardsLayout list-unstyled';
playedCards.className = 'playedCardsLayout list-unstyled';
playedCards.style.width = '160px';
playedCards.style.marginLeft = '25px';
playedCards.style.left = shift*129 + 'px';
node.appendChild(playedCards);
}
createCardPlace(1, 0, document.getElementById('playedHigh'));
for(let i = 14; i > 8; i--) {
createCardPlace(i, 14 - i + 1, document.getElementById('playedHigh'));
}
for(let i = 8; i > 1; i--) {
createCardPlace(i, 8 - i, document.getElementById('playedLow'));
}
var smartFoldButton = document.createElement('button');
smartFoldButton.className = "btn btn-danger btn-xs";
smartFoldButton.id = "smartFold";
smartFoldButton.type = "button";
smartFoldButton.innerHTML = 'Smart fold: <span id="smartFoldValue" data-on="Yes" data-off="No">Yes</span>';
var showPlayedButton = document.createElement('button');
showPlayedButton.className = "btn btn-primary btn-xs";
showPlayedButton.id = "showPlayed";
showPlayedButton.type = "button";
showPlayedButton.innerHTML = 'Show counted cards: <span id="showPlayedValue" data-on="Yes" data-off="No">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.insertBefore(showRemainingButton, document.getElementById('autoFold'));
buttons.insertBefore(showPlayedButton, document.getElementById('autoFold'));
buttons.insertBefore(smartFoldButton, document.getElementById('autoFold'));
// playedCards.
// ot.$gameField.insertAfter(playedCards, ot.$gameField.lastChild);
// set up counting of played cards
var OnlineTichuCounter = {
$playedCards: {},
$smartFold: $('#smartFold'),
$smartFoldValue: $('#smartFoldValue'),
$showPlayed: $('#showPlayed'),
$showPlayedValue: $('#showPlayedValue'),
$showRemaining: $('#showRemaining'),
$showRemainingValue: $('#showRemainingValue'),
$playedHigh: $('#playedHigh'),
$playedLow: $('#playedLow'),
allCards: {},
playedCards: {},
totalPlayed: [],
exchangedTo: {},
exchangedFrom: {},
smartFold: true,
showPlayed: false,
showRemaining: true,
bombAfterFold: null,
util: {
displayCardsHtmlString: function(cards) {
htmlString = "";
$(cards).each(function () {
var value = this.Value;
if (this.Shape == 7) {
value = 0;
} }
otc.$playedCards[i].html(otc.util.displayCardsHtmlString(cards)); htmlString += '<li id="c' + this.Shape + '-' + value
+ '" class="card c' + this.Shape + '-' + value
+ '" data-shape="' + this.Shape + '" data-value="'
+ value + '"></li>';
});
return htmlString;
},
populateAllCards: function() {
for(let val = 2; val < 15; val++) {
otc.allCards[val] = [];
for(let shape = 0; shape < 4; shape++) {
otc.allCards[val].push({
Shape: shape,
Value: val
});
}
}
otc.allCards[1] = [
{ Shape: 4, Value: 1 }, // mahjong
{ Shape: 5, Value: 0 }, // dog
{ Shape: 6, Value: 15}, // dragon
{ Shape: 7, Value: 14 } // phoenix
];
},
cardInArray: function(card, array) {
contained = false;
for(let i = 0; i < array.length; i++) {
if (array[i].Shape == card.Shape && array[i].Value == card.Value) {
contained = true;
}
}
return contained;
}
},
action: {
handlePlayedCard: function(card) {
index = 0;
// special cards have Shapes 4,5,6,7. We group them at value 1
if(card.Shape >= 4) {
index = 1;
if (card.Shape == 7) {
// Treat phoenix as if it had value 14
// This is important for comparisons later
card.Value = 14;
} }
} else { } else {
otc.$playedCards[i].html(otc.util.displayCardsHtmlString(otc.playedCards[i])); index = card.Value;
} }
} otc.playedCards[index].push(card);
} otc.totalPlayed.push(card);
}
}
if (!window.otc) { otc.playedCards[index].sort(function(c1, c2){
window.otc = OnlineTichuCounter; return c2.Shape - c1.Shape;
} });
},
// add functionality to smartFold button handlePlayedCards: function(cards) {
otc.$smartFold.click(function () { if (cards.length === 0) {
otc.smartFold = !otc.smartFold; return;
if (otc.smartFold) { }
otc.$smartFoldValue.text(otc.$smartFoldValue.data('on')); if (!otc.util.cardInArray(cards[0], otc.totalPlayed)) {
} else { $(message.Table.TableCards).each(
otc.$smartFoldValue.text(otc.$smartFoldValue.data('off')); (index, card) => otc.action.handlePlayedCard(card)
} );
}); }
},
// add functionality to show button resetPlayedCards: function() {
otc.$showPlayed.click(function () { for(let i = 1; i < 15; i++) {
otc.showPlayed = !otc.showPlayed; otc.playedCards[i] = [];
if (otc.showPlayed) { }
otc.$showPlayedValue.text(otc.$showPlayedValue.data('on')); otc.totalPlayed = [];
otc.$playedHigh.show(); },
otc.$playedLow.show();
otc.$showRemaining.show();
} else {
otc.$showPlayedValue.text(otc.$showPlayedValue.data('off'));
otc.$playedHigh.hide();
otc.$playedLow.hide();
otc.$showRemaining.hide();
}
});
otc.$showRemaining.click(function () { drawPlayedCards: function() {
otc.showRemaining = !otc.showRemaining; for(let i = 1; i < 15; i++) {
if (otc.showRemaining) { if (otc.showRemaining) {
otc.$showRemainingValue.text(otc.$showRemainingValue.data('on')); cards = [];
} else { for(let j=0; j < otc.allCards[i].length; j ++) {
otc.$showRemainingValue.text(otc.$showRemainingValue.data('off')); if(!otc.util.cardInArray(otc.allCards[i][j], otc.playedCards[i])) {
} cards.push(otc.allCards[i][j]);
otc.action.drawPlayedCards(); }
}); otc.$playedCards[i].html(otc.util.displayCardsHtmlString(cards));
for(let i = 1; i < 15; i++) {
otc.$playedCards[i] = $('#playedCards' + i);
}
otc.action.resetPlayedCards();
otc.util.populateAllCards();
MyTableState = (function() {
var cachedFunction = ot.reaction.TableState;
return function() {
var result = cachedFunction.apply(this, arguments);
message = arguments[0];
// console.log('detected table state change event');
// console.log(message.Table.Status);
// reset played cards at start of round
if(message.Table.Status == 'WaitForNextCards') {
otc.action.resetPlayedCards();
}
if(message.Table.Status == 'Playing') {
otc.action.handlePlayedCards(message.Table.TableCards);
}
otc.action.drawPlayedCards();
console.log('reached smartFold point');
$(message.Table.Players).each(function () {
if (this.Username == ot.$Username.val()) {
console.log('found player');
if (message.Table.Turn == this.Position) {
console.log('my turn!');
if (this.Cards.length < 4 && this.Cards.length < message.Table.TableCards.length) {
console.log('obvious that have to fold now');
if (otc.smartFold) {
ot.action.Fold();
} }
} else {
otc.$playedCards[i].html(otc.util.displayCardsHtmlString(otc.playedCards[i]));
} }
} }
} }
}); }
return result;
} }
})(); if (!window.otc) {
window.otc = OnlineTichuCounter;
}
otc.$showRemaining.hide();
MyChat = (function() { // add functionality to smartFold button
var cachedFunction = ot.reaction.Chat; otc.$smartFold.click(function () {
otc.smartFold = !otc.smartFold;
if (otc.smartFold) {
otc.$smartFoldValue.text(otc.$smartFoldValue.data('on'));
} else {
otc.$smartFoldValue.text(otc.$smartFoldValue.data('off'));
}
});
return function() { // add functionality to show button
var result = cachedFunction.apply(this, arguments); otc.$showPlayed.click(function () {
otc.showPlayed = !otc.showPlayed;
if (otc.showPlayed) {
otc.$showPlayedValue.text(otc.$showPlayedValue.data('on'));
otc.$playedHigh.show();
otc.$playedLow.show();
otc.$showRemaining.show();
} else {
otc.$showPlayedValue.text(otc.$showPlayedValue.data('off'));
otc.$playedHigh.hide();
otc.$playedLow.hide();
otc.$showRemaining.hide();
}
});
message = arguments[0]; otc.$showRemaining.click(function () {
if (message.User.Username === "System") { otc.showRemaining = !otc.showRemaining;
var messageArray = message.Text.replace(/</g, '&lt;').replace(/>/g, '&gt;').split(' '); if (otc.showRemaining) {
message.Text = messageArray.join(' '); otc.$showRemainingValue.text(otc.$showRemainingValue.data('on'));
messageArray = message.Text.replace(/</g, '&lt;').replace(/>/g, '&gt;').split(' '); } else {
otc.$showRemainingValue.text(otc.$showRemainingValue.data('off'));
for(var i in messageArray) { }
if(messageArray[i] == "dogs") { otc.action.drawPlayedCards();
otc.action.handlePlayedCard({ });
"Shape": 5,
"Value": 0 for(let i = 1; i < 15; i++) {
}); otc.$playedCards[i] = $('#playedCards' + i);
} }
otc.action.resetPlayedCards();
otc.util.populateAllCards();
MyTableState = (function() {
var cachedFunction = ot.reaction.TableState;
return function() {
var result = cachedFunction.apply(this, arguments);
message = arguments[0];
// console.log('detected table state change event');
// console.log(message.Table.Status);
// reset played cards at start of round
if(message.Table.Status == 'WaitForNextCards') {
otc.action.resetPlayedCards();
} }
if(message.Table.Status == 'Playing') {
otc.action.handlePlayedCards(message.Table.TableCards);
}
otc.action.drawPlayedCards();
console.log('reached smartFold point');
$(message.Table.Players).each(function () {
if (this.Username == ot.$Username.val()) {
console.log('found player');
if (message.Table.Turn == this.Position) {
console.log('my turn!');
if (this.Cards.length < 4 && this.Cards.length < message.Table.TableCards.length) {
console.log('obvious that have to fold now');
if (otc.smartFold) {
ot.action.Fold();
}
}
}
}
});
return result;
} }
return result; })();
}
})();
MyExchangeCards = (function() {
var cachedFunction = ot.action.ExchangeCards;
return function() { MyChat = (function() {
var cachedFunction = ot.reaction.Chat;
otc.exchangedTo['west'] = { return function() {
Shape: ot.$westExchange.children('li:nth-child(1)').data('shape'), var result = cachedFunction.apply(this, arguments);
Value: ot.$westExchange.children('li:nth-child(1)').data('value') };
otc.exchangedTo['north'] = {
Shape: ot.$northExchange.children('li:nth-child(1)').data('shape'),
Value: ot.$northExchange.children('li:nth-child(1)').data('value') };
otc.exchangedTo['east'] = {
Shape: ot.$eastExchange.children('li:nth-child(1)').data('shape'),
Value: ot.$eastExchange.children('li:nth-child(1)').data('value') };
console.log(otc.exchangedTo); message = arguments[0];
if (message.User.Username === "System") {
var messageArray = message.Text.replace(/</g, '&lt;').replace(/>/g, '&gt;').split(' ');
message.Text = messageArray.join(' ');
messageArray = message.Text.replace(/</g, '&lt;').replace(/>/g, '&gt;').split(' ');
for(var i in messageArray) {
if(messageArray[i] == "dogs") {
otc.action.handlePlayedCard({
"Shape": 5,
"Value": 0
});
}
}
}
var result = cachedFunction.apply(this, arguments); return result;
return result; }
} })();
})();
MyReviewExchange = (function() { MyExchangeCards = (function() {
var cachedFunction = ot.reaction.ReviewExchange; var cachedFunction = ot.action.ExchangeCards;
return function() { return function() {
var result = cachedFunction.apply(this, arguments);
return result;
}
})();
ot.reaction.TableState = MyTableState; otc.exchangedTo['west'] = {
ot.reaction.Chat = MyChat; Shape: ot.$westExchange.children('li:nth-child(1)').data('shape'),
ot.action.ExchangeCards = MyExchangeCards; Value: ot.$westExchange.children('li:nth-child(1)').data('value') };
otc.exchangedTo['north'] = {
Shape: ot.$northExchange.children('li:nth-child(1)').data('shape'),
Value: ot.$northExchange.children('li:nth-child(1)').data('value') };
otc.exchangedTo['east'] = {
Shape: ot.$eastExchange.children('li:nth-child(1)').data('shape'),
Value: ot.$eastExchange.children('li:nth-child(1)').data('value') };
console.log(otc.exchangedTo);
var result = cachedFunction.apply(this, arguments);
return result;
}
})();
MyReviewExchange = (function() {
var cachedFunction = ot.reaction.ReviewExchange;
return function() {
var result = cachedFunction.apply(this, arguments);
return result;
}
})();
ot.reaction.TableState = MyTableState;
ot.reaction.Chat = MyChat;
ot.action.ExchangeCards = MyExchangeCards;
};
// Special care is to be taken to safely inject our javascript into the websiet
// without the website being able to talk back to greasemonkey
// (which would be a security problem)
// see
// https://stackoverflow.com/questions/5006460/userscripts-greasemonkey-calling-a-websites-javascript-functions
// and the excellent answer by Wayne for details on this
function exec(fn) {
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '(' + fn + ')();';
document.body.appendChild(script); // run the script
document.body.removeChild(script); // clean up
}
exec(injectCounter);