Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draw offers #39

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
f2d93cc
Revert "Reapply "Add more reserved usernames""
this-is-not-available Jul 10, 2024
2e9de91
Add frontend
this-is-not-available Jul 10, 2024
b3ab717
Reapply "Add more reserved usernames"
this-is-not-available Jul 10, 2024
9e2c00d
Merge branch 'main' into draw-offers
this-is-not-available Jul 10, 2024
60b0c6d
Corrected game conclusion. It should be 2 words
Naviary2 Jul 10, 2024
105faed
Game ending by draw offer should now display "Draw by agreement."
Naviary2 Jul 10, 2024
18ac3e6
Draw offer spam protection
this-is-not-available Jul 11, 2024
6730ed3
Minor adjustments
this-is-not-available Jul 11, 2024
f4af98c
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 11, 2024
93b049f
Move dev.css to correct place
this-is-not-available Jul 11, 2024
e6ce3c2
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 11, 2024
1248ea6
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 11, 2024
9f14473
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 11, 2024
1bf3075
Frontend changes
this-is-not-available Jul 11, 2024
9939ada
Add statustext for decliner
this-is-not-available Jul 11, 2024
d14373f
Don't obscure timers
this-is-not-available Jul 11, 2024
bec833b
Fixed bug
Naviary2 Jul 11, 2024
e8b57b1
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 11, 2024
077ddba
Refreshing no longer breaks draw offers
this-is-not-available Jul 11, 2024
b259246
Merge branch 'draw-offers' of https://github.com/this-is-not-availabl…
this-is-not-available Jul 11, 2024
7231b72
Move whosturn above draw offer
this-is-not-available Jul 11, 2024
f60e1e2
Revert "Move whosturn above draw offer"
this-is-not-available Jul 19, 2024
f907c10
Revert "Don't obscure timers"
this-is-not-available Jul 19, 2024
f6e238b
It looks good according to jermOSS
this-is-not-available Jul 19, 2024
059bac5
typo i think fixed
this-is-not-available Jul 19, 2024
54782e9
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 19, 2024
e9685d8
No longer popup
this-is-not-available Jul 19, 2024
22e52f8
Button is white and icons bigger
this-is-not-available Jul 19, 2024
ed695b7
Add comment
this-is-not-available Jul 19, 2024
f6f5d4e
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 20, 2024
ad61716
Added translations and added missing HTML
this-is-not-available Jul 20, 2024
e13ee01
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 23, 2024
b99765f
Not working :sob:
this-is-not-available Jul 23, 2024
6af3052
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 25, 2024
df6c8d5
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 26, 2024
a82a348
Merge branch 'Infinite-Chess:main' into draw-offers
this-is-not-available Jul 29, 2024
2fe49aa
Fixed logic and moved to guidrawoffer.js
this-is-not-available Jul 29, 2024
2eb5c20
Added termination to translation
this-is-not-available Jul 29, 2024
f593b5e
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
this-is-not-available Jul 29, 2024
946fa6a
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 29, 2024
a53bac0
yes
this-is-not-available Jul 29, 2024
e08fe9f
Increment version
this-is-not-available Jul 29, 2024
70083a7
Gui autocloses
this-is-not-available Jul 29, 2024
1ee720d
snake case
this-is-not-available Jul 29, 2024
361f9a7
??? it no transparent whyyyyy
this-is-not-available Jul 29, 2024
f42843d
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Jul 31, 2024
999e811
Translations and accept draw in pause menu
this-is-not-available Jul 31, 2024
4765fea
Don't carry accept draw to other game
this-is-not-available Jul 31, 2024
36eafe2
Moved automatic draw declining
this-is-not-available Jul 31, 2024
4c139cf
Fix previous to include closing of UI
this-is-not-available Jul 31, 2024
d8fe840
Server-sided auto declining
this-is-not-available Jul 31, 2024
f6a515b
Fixed perspective button
this-is-not-available Jul 31, 2024
6515d2d
Adjust font
this-is-not-available Jul 31, 2024
20b19aa
Merge branch 'Infinite-Chess:main' into draw-offers
this-is-not-available Jul 31, 2024
8b2f01f
JSDoc stuff
this-is-not-available Jul 31, 2024
e6bb926
Merge branch 'draw-offers' of https://github.com/this-is-not-availabl…
this-is-not-available Jul 31, 2024
a108e41
whoops missed a change
this-is-not-available Jul 31, 2024
f6e8446
stuff
this-is-not-available Jul 31, 2024
ffacad2
Move it inside other div
this-is-not-available Aug 1, 2024
b0b2a73
Remove the footer class
this-is-not-available Aug 1, 2024
9a9db2a
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Aug 1, 2024
6154633
Update version in toml
this-is-not-available Aug 1, 2024
a921774
Bug fix and hasColorDrawOffer
this-is-not-available Aug 1, 2024
5c61d4b
fix bugs
this-is-not-available Aug 1, 2024
8a1b348
Add config variable
this-is-not-available Aug 2, 2024
ff3a544
Change sound and remove some lines
this-is-not-available Aug 2, 2024
dc30b82
CSS improvements
this-is-not-available Aug 2, 2024
1a35425
Math fix :O
this-is-not-available Aug 3, 2024
d999a5f
Whoops wrong ordering in css
this-is-not-available Aug 3, 2024
69aec44
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Aug 3, 2024
f3ea438
Fix bug (found another)
this-is-not-available Aug 4, 2024
43ee31f
Other
this-is-not-available Aug 4, 2024
7f7d859
Bug fix
this-is-not-available Aug 4, 2024
111c126
Merge branch 'Infinite-Chess:main' into draw-offers
this-is-not-available Aug 5, 2024
f0e353a
Bug fix (client edition)
this-is-not-available Aug 5, 2024
78d4ad9
Merge branch 'draw-offers' of https://github.com/this-is-not-availabl…
this-is-not-available Aug 5, 2024
211fb6c
moved sound spritesheet with draw offer sound to dev utils
Naviary2 Aug 6, 2024
bc0c897
Lots of cleaning up
Naviary2 Aug 6, 2024
aa9167e
Merge remote-tracking branch 'upstream/main' into draw-offers
this-is-not-available Aug 6, 2024
cd8414b
reorder the code
this-is-not-available Aug 6, 2024
e4e7789
Fix uhhh.. what do i put here
this-is-not-available Aug 6, 2024
6687ee0
Add vendor specific to css
this-is-not-available Aug 6, 2024
df1324f
Moved many methods from gamemanager to new game1.js
Naviary2 Aug 9, 2024
8558ca0
Merge branch 'draw-offers' of https://github.com/this-is-not-availabl…
Naviary2 Aug 9, 2024
c831d4f
deleted whitespace
Naviary2 Aug 9, 2024
e6d48a5
Merge branch 'main' into draw-offers
Naviary2 Aug 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions game/TypeDefinitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ function Game() {
* AFK if they are currently AFK. */
this.autoAFKResignTime = undefined;

/** Last move a draw was offered */
this.drawOfferMove = undefined

/** Information about players offering a draw */
this.whiteDrawOffer = undefined
this.blackDrawOffer = undefined

/** Contains information about which sides are
* about to lose by disconnection. */
this.disconnect = {
Expand Down
123 changes: 122 additions & 1 deletion game/gamemanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ const gamemanager = (function() {
blackSocket: undefined,
timeNextPlayerLosesAt: undefined,
autoTimeLossTimeoutID: undefined,
whiteDrawOffer: undefined,
blackDrawOffer: undefined,
disconnect: {
startTimer: {
white: undefined,
Expand Down Expand Up @@ -792,6 +794,106 @@ const gamemanager = (function() {
sendGameUpdateToColor(game, opponentColor);
}


/**
* Called when client wants to offer a draw
* Sends confirmation to opponents
* @param {Socket} ws - The socket
*/
function offerDraw(ws) {
console.log("Client offers a draw.")

const game = getGameBySocket(ws);
if (!game) return console.error("Client offered a draw when they don't belong in a game.")
const color = doesSocketBelongToGame_ReturnColor(game, ws);

if (isGameOver(game)) return console.error("Client offered a draw when the game is already over. Ignoring.");

if (hasGameDrawOffer(game)) return console.error("Client offered a draw when the game has a draw offer");

if (game.moves.length > game.drawOfferMove) return console.error("Client trying to offer a draw twice on the same move")

// Update the status of game
if (color === 'white') {
game.whiteDrawOffer = 'offered'
game.blackDrawOffer = 'unconfirmed'
} else if (color === 'black') {
game.blackDrawOffer = 'offered'
game.whiteDrawOffer = 'unconfirmed'
}

// Alert their opponent
const opponentColor = math1.getOppositeColor(color);
const value = { offererColor: color }
sendMessageToSocketOfColor(game, opponentColor, 'game', 'drawoffer', value)
}

/**
* Called when client accepts a draw
* Ends the game
* @param {Socket} ws - The socket
*/
function acceptDraw(ws) {
console.log("Client accepts a draw.")

const game = getGameBySocket(ws);
if (!game) return console.error("Client accepted a draw when they don't belong in a game.")
const color = doesSocketBelongToGame_ReturnColor(game, ws);
const opponentColor = math1.getOppositeColor(color);

if (isGameOver(game)) return console.error("Client accepted a draw when the game is already over. Ignoring.");

// Update the status of game
if (color === 'white') {
if (!hasGameDrawOffer(game)) return console.error("Client accepted a draw when there wasn't a draw offer")
game.whiteDrawOffer = 'confirmed'
} else if (color === 'black') {
if (!hasGameDrawOffer(game)) return console.error("Client accepted a draw when there wasn't a draw offer")
game.blackDrawOffer = 'confirmed'
}
setGameConclusion(game, "draw agreement")

// End the game
onRequestRemovalFromPlayersInActiveGames(ws);
unsubClientFromGame(ws, { sendMessage: false });
sendGameUpdateToColor(game, opponentColor);

const opponentWs = opponentColor === 'black' ? game.blackSocket : game.whiteSocket
onRequestRemovalFromPlayersInActiveGames(opponentWs);
unsubClientFromGame(opponentWs, { sendMessage: false });
sendGameUpdateToColor(game, color); // wasteful to send update here, but im lazy to figure out how to set client to show it drawed
}

/**
* Called when client declines a draw
* Alerts opponent
* @param {Socket} ws - The socket
*/
function declineDraw(ws) {
console.log("Client declines a draw.")

const game = getGameBySocket(ws);
if (!game) return console.error("Client declined a draw when they don't belong in a game.")
const color = doesSocketBelongToGame_ReturnColor(game, ws);
const opponentColor = math1.getOppositeColor(color);

if (isGameOver(game)) return console.error("Client declined a draw when the game is already over. Ignoring.");

// Update the status of game
if (color === 'white') {
if (!hasGameDrawOffer(game)) return console.error("Client declined a draw when there wasn't a draw offer")
game.whiteDrawOffer = 'declined'
game.blackDrawOffer = undefined
} else if (color === 'black') {
if (!hasGameDrawOffer(game)) return console.error("Client declined a draw when there wasn't a draw offer")
game.blackDrawOffer = 'declined'
game.whiteDrawOffer = undefined
}

// Alert their opponent
sendMessageToSocketOfColor(game, opponentColor, 'game', 'declinedraw')
}

/**
* Called when a client alerts us they have gone AFK.
* Alerts their opponent, and starts a timer to auto-resign.
Expand Down Expand Up @@ -1071,6 +1173,19 @@ const gamemanager = (function() {
function isGameOver(game) { return game.gameConclusion !== false; }

/**

* Returns *true* if the provided game has a draw offer.
* Games that have a draw offer can't make moves, until draw is accepted or declined.
* @param {Game} game - The game
* @returns {boolean}
*/
function hasGameDrawOffer(game) {
const isOffering = (game.blackDrawOffer === 'offered' || game.whiteDrawOffer === 'offered')
return isOffering
}

/**

* Handles all incoming websocket messages related to active games.
* Possible actions: submitmove/offerdraw/abort/resign/joingame/resync
* @param {Socket} ws - The socket
Expand All @@ -1097,7 +1212,13 @@ const gamemanager = (function() {
resignGame(ws)
break;
case 'offerdraw':
console.error("Don't know how to offer draw yet.")
offerDraw(ws);
break;
case 'acceptdraw':
acceptDraw(ws);
break;
case 'declinedraw':
declineDraw(ws);
break;
case 'AFK':
onAFK(ws);
Expand Down
53 changes: 51 additions & 2 deletions protected-owner/css/dev.css
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ button.join-button, button.copy-button {
background-color: rgba(0, 0, 0, 0.849);
padding-bottom: 15vh;
display: grid;
grid-template: repeat(5, min(8vw, 86px)) / repeat(2, min(30vw, 320px));
grid-template: repeat(6, min(8vw, 86px)) / repeat(2, min(30vw, 320px));
gap: min(3vw, 32px);
justify-content: center;
align-content: center;
Expand Down Expand Up @@ -1247,11 +1247,60 @@ button.join-button, button.copy-button {
background: linear-gradient(to bottom, white, rgb(230, 230, 230), white);
}

.pauseUI p.paused, button.paused, button.resume, button.mainmenu {
.pauseUI p.paused, button.paused, button.resume, button.mainmenu, button.offerdraw {
grid-column: 1 / 3;
}


/* Draw Offer UI */

.drawOfferUI {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.849);
padding: 15vh;
padding-left: 35vh;
padding-right: 35vh;
display: flex;
flex-direction: column;
gap: min(3vw, 32px);
justify-content: center;
align-content: center;
}

.drawOfferUI p.offertitle, .drawOfferUI button {
font-size: min(2.5vw, 27px);
}

.drawOfferUI p.offertitle {
color: white;
text-align: center;
/*align-self: center;*/
}

.drawOfferUI button {
background-color: rgb(228, 228, 228);
box-shadow: 0 0 10px 0 rgba(255, 255, 255, 0.27);
border-radius: min(0.9vw, 10px);
color: rgb(0, 0, 0);
height: 10%;
background: linear-gradient(to bottom, white, rgb(199, 199, 199), white);
}

.drawOfferUI button:hover {
/* background-color: rgb(255, 255, 255); */
background: linear-gradient(to bottom, white, rgb(219, 219, 219), white);
}

.drawOfferUI button:active {
/* box-shadow: 0 0 15px 0 rgba(255, 255, 255, 0.51); */
background: linear-gradient(to bottom, white, rgb(230, 230, 230), white);
}



/* Status text showing alerts and errors */

Expand Down
3 changes: 3 additions & 0 deletions protected-owner/scripts/game/gamefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ function gamefile(metadata, { moves = [], variantOptions, gameConclusion } = {})
this.attackers = undefined;
/** If 3-Check is enabled, this is a running count of checks given: `{ white: 0, black: 0 }` */
this.checksGiven = undefined;
/** The last move when a draw offer was given
* Used for disabling the button */
this.LastDrawOfferMove = undefined;

this.ourPieces = organizedlines.buildStateFromKeyList(this.startSnapshot.position)
this.startSnapshot.pieceCount = gamefileutility.getPieceCountOfGame(this)
Expand Down
75 changes: 73 additions & 2 deletions protected-owner/scripts/game/gui/guipause.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ const guipause = (function(){
const element_copygame = document.getElementById('copygame')
const element_pastegame = document.getElementById('pastegame')
const element_mainmenu = document.getElementById('mainmenu')
const element_offerDraw = document.getElementById('offerdraw')
const element_perspective = document.getElementById('toggleperspective')

// Draw Offer UI
let isAcceptingDraw = false
const element_drawOfferUI = document.getElementById('drawOfferUI')
const element_acceptDraw = document.getElementById('acceptdraw')
const element_declineDraw = document.getElementById('declinedraw')

// Functions

Expand All @@ -27,6 +34,12 @@ const guipause = (function(){
*/
function areWePaused() { return isPaused; }

/**
* Returns *true* if the user is deciding on accepting draw.
* @returns {boolean}
*/
function areWeAcceptingDraw() { return isAcceptingDraw; }

function gelement_perspective() {
return element_perspective;
}
Expand All @@ -35,10 +48,18 @@ const guipause = (function(){
isPaused = true;
changeTextOfMainMenuButton()
updatePasteButtonTransparency()
updateDrawOfferButtonTransparency()
style.revealElement(element_pauseUI)
initListeners()
}

function openDrawOffer() {
isAcceptingDraw = true;
style.revealElement(element_drawOfferUI)
sound.playSound_drawOffer()
initListeners()
}

function toggle() {
if (!isPaused) open();
else callback_Resume()
Expand All @@ -50,7 +71,18 @@ const guipause = (function(){
const legalInPrivateMatch = onlinegame.getIsPrivate() && (movesLength === 0 || moves[0].length === 1 && moves[0][0] == null);

if (onlinegame.areInOnlineGame() && !legalInPrivateMatch) element_pastegame.classList.add('opacity-0_5')
else element_pastegame.classList.remove('opacity-0_5')
else element_pastegame.classList.remove('opacity-0_5')
}

function updateDrawOfferButtonTransparency() {
const gamefile = game.getGamefile()
const moves = gamefile.moves;
const movesLength = moves.length;

const RecentDrawOffers = movesLength > gamefile.LastDrawOfferMove ? false : true

if (!onlinegame.areInOnlineGame() || RecentDrawOffers) element_pastegame.classList.add('opacity-0_5')
else element_pastegame.classList.remove('opacity-0_5')
}

function changeTextOfMainMenuButton() {
Expand All @@ -69,7 +101,11 @@ const guipause = (function(){
element_copygame.addEventListener('click', copypastegame.callbackCopy)
element_pastegame.addEventListener('click', copypastegame.callbackPaste)
element_mainmenu.addEventListener('click', callback_MainMenu)
element_offerDraw.addEventListener('click', callback_OfferDraw)
element_perspective.addEventListener('click', callback_Perspective)

element_acceptDraw.addEventListener('click', callback_AcceptDraw)
element_declineDraw.addEventListener('click', callback_DeclineDraw)
}

function closeListeners() {
Expand All @@ -78,14 +114,20 @@ const guipause = (function(){
element_copygame.removeEventListener('click', copypastegame.callbackCopy)
element_pastegame.removeEventListener('click', copypastegame.callbackPaste)
element_mainmenu.removeEventListener('click', callback_MainMenu)
element_offerDraw.removeEventListener('click', callback_OfferDraw)
element_perspective.removeEventListener('click', callback_Perspective)

element_acceptDraw.removeEventListener('click', callback_AcceptDraw)
element_declineDraw.removeEventListener('click', callback_DeclineDraw)
}

function callback_Resume(event) {
if (!isPaused) return;
if (!isPaused && !isAcceptingDraw) return;
event = event || window.event;
isPaused = false;
isAcceptingDraw = false;
style.hideElement(element_pauseUI)
style.hideElement(element_drawOfferUI)
closeListeners()
main.renderThisFrame();
}
Expand All @@ -101,6 +143,30 @@ const guipause = (function(){
guititle.open()
}

async function callback_OfferDraw(event) {
onlinegame.offerDraw()
callback_Resume()
statustext.showStatus(`Waiting for opponent to accept draw...`, false, 3)
}

async function callback_AcceptDraw(event) {
onlinegame.acceptDraw()
// gamefile.gameConclusion = 'draw agreement'
// gamefileutility.concludeGame(gamefile)
callback_Resume()

const gamefile = game.getGamefile();
gamefile.gameConclusion = 'draw agreement';
clock.stop()
if (gamefile.gameConclusion) gamefileutility.concludeGame(gamefile);
}

async function callback_DeclineDraw(event) {
onlinegame.declineDraw()
callback_Resume()
statustext.showStatus(`Draw declined`, false, 2)
}

function callback_TogglePointers (event) {
event = event || window.event;
main.renderThisFrame();
Expand All @@ -122,12 +188,17 @@ const guipause = (function(){

return Object.freeze({
areWePaused,
areWeAcceptingDraw,
gelement_perspective,
open,
toggle,
changeTextOfMainMenuButton,
callback_Resume,
callback_TogglePointers,
callback_OfferDraw,
callback_AcceptDraw,
callback_DeclineDraw,
openDrawOffer
})

})();
Loading