217 lines
12 KiB
JavaScript
217 lines
12 KiB
JavaScript
import React from "react";
|
|
import io from "socket.io-client"
|
|
import pako from "pako";
|
|
import * as Act from "./interface/Actions";
|
|
import Store from "./interface/Store";
|
|
import Players from "./Players"
|
|
import WinStats from "./WinStats"
|
|
import SerStats from "./SeriesStats";
|
|
import settings from "../settings";
|
|
import retImg from "./Images/goback.png"
|
|
import bp1Img from "./Images/spkron.png"
|
|
import bp2Img from "./Images/spkroff.png"
|
|
|
|
export default class Game extends React.Component {
|
|
constructor() {
|
|
super()
|
|
this.state = {
|
|
auth: Store.getToken(),
|
|
players: [], hand: [], turn: [], status: 0, atr: 0,
|
|
live: false, msg: '', noise: true,
|
|
myturn: false, coin: 0, avail: [],
|
|
}
|
|
this.color = ['grey', 'red', 'green', 'blue']
|
|
this.card = []
|
|
this.hand = []
|
|
|
|
this.connect = this.connect.bind(this)
|
|
this.boardCard = this.boardCard.bind(this)
|
|
this.dealtCard = this.dealtCard.bind(this)
|
|
this.player = this.player.bind(this)
|
|
this.status = this.status.bind(this)
|
|
this.myturn = this.myturn.bind(this)
|
|
|
|
this.onDragStart = this.onDragStart.bind(this)
|
|
this.onDragOver = this.onDragOver.bind(this)
|
|
this.onDrop = this.onDrop.bind(this)
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.socket = io.connect(settings.server.baseSite,
|
|
{ query: 'token=' + this.state.auth + '&game=' + this.props.game })
|
|
this.socket.on('connect', this.connect)
|
|
this.socket.on('boardCard', this.boardCard)
|
|
this.socket.on('dealtCard', this.dealtCard)
|
|
this.socket.on('player', this.player)
|
|
this.socket.on('status', this.status)
|
|
this.socket.on('myturn', this.myturn)
|
|
this.socket.emit('reqBoardCards', { id: 'BRDCRD' })
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.socket.emit('disconnect', { id: 'PLYERS', act: 0, soc: '' })
|
|
this.socket.disconnect()
|
|
}
|
|
|
|
connect() {
|
|
this.socket.emit('reqPlayers', { id: 'PLYERS', act: 1 })
|
|
}
|
|
|
|
boardCard(data) {
|
|
const binData = new Uint8Array(data);
|
|
const obj = JSON.parse(pako.inflate(binData, { to: 'string' }));
|
|
const node = this.card[obj.crd]
|
|
node.innerHTML = obj.img;
|
|
}
|
|
|
|
dealtCard(data) {
|
|
const binData = new Uint8Array(data);
|
|
const obj = JSON.parse(pako.inflate(binData, { to: 'string' }));
|
|
const node = this.hand[obj.inx]
|
|
node.innerHTML = obj.img;
|
|
|
|
let hand = this.state.hand
|
|
hand[obj.inx] = { dlr: obj.dlr }
|
|
this.setState({ hand: hand })
|
|
}
|
|
|
|
player(data) {
|
|
let obj = data
|
|
this.setState({ players: obj.players, live: obj.live })
|
|
if (obj.live === true) {
|
|
this.socket.emit('reqDealtHand', { id: 'DLTHND' })
|
|
} else {
|
|
for (let i = 0; i < this.hand.length; i++) {
|
|
const node = this.hand[i]
|
|
while (node.firstChild) node.removeChild(node.firstChild);
|
|
}
|
|
}
|
|
}
|
|
|
|
status(data) {
|
|
let obj = data
|
|
this.setState({ turn: obj.turn, msg: obj.msg, atr: obj.atr, status: Number(obj.typ) })
|
|
if (obj.typ === 1) {
|
|
Act.apiCall('service', 'GMSTAT', { match: this.props.game })
|
|
this.setState({ myturn: false, coin: 0 })
|
|
} else if (obj.typ === 2) {
|
|
this.socket.emit('reqDealtHand', { id: 'DLTHND' })
|
|
this.setState({status: 0})
|
|
}
|
|
}
|
|
|
|
myturn(data) {
|
|
let obj = data
|
|
this.setState({ myturn: true, coin: obj.coin, avail: obj.avail })
|
|
if (this.state.noise) this.beep()
|
|
}
|
|
|
|
newgame() {
|
|
this.socket.emit('reqNewGame', { id: 'GAMREQ' })
|
|
}
|
|
|
|
leave() {
|
|
this.props.xout()
|
|
}
|
|
|
|
beep() {
|
|
var snd = new Audio("data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
|
|
snd.play();
|
|
}
|
|
|
|
onDragStart(ev, id) {
|
|
ev.dataTransfer.setData("id", id);
|
|
let inx = Number(id.substr(1));
|
|
let dlr = this.state.hand[inx].dlr
|
|
for (let i = 0; i < this.state.avail.length; i++) {
|
|
if (this.state.avail[i].dlr === dlr) {
|
|
this.state.avail[i].p.map((x) => {
|
|
const node = this.card[x]
|
|
node.addEventListener('dragover', this.onDragOver);
|
|
// console.log("d:" + dlr + " i:" + i + " c:" + x)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
onDragOver(ev) {
|
|
ev.preventDefault();
|
|
}
|
|
|
|
onDrop(ev, msg) {
|
|
let id = ev.dataTransfer.getData("id");
|
|
let inx = Number(id.substr(1));
|
|
//console.log("I:" + inx + " B:" + msg.substr(1) + " D:" + this.state.hand[inx].dlr)
|
|
this.socket.emit('PlayCard', { id: 'CRDPLY', crd: msg.substr(1), inx: inx, dlr: this.state.hand[inx].dlr })
|
|
this.setState({ myturn: false, coin: 0 })
|
|
for (let i = 0; i < this.card.length; i++) {
|
|
const node = this.card[i]
|
|
node.removeEventListener('dragover', this.onDragOver);
|
|
}
|
|
}
|
|
|
|
render() {
|
|
let dec = []
|
|
for (let i = 0; i < 100; i++) {
|
|
dec.push(<div className="card"
|
|
onDrop={(e) => this.onDrop(e, 'X' + i)}
|
|
ref={(component) => { this.card[i] = component; }} >
|
|
</div>)
|
|
}
|
|
|
|
let hnd = []
|
|
for (let i = 0; i < this.props.deal; i++) {
|
|
hnd.push(<div id="dealt" className="dealt">
|
|
{this.state.live && this.state.myturn === true
|
|
? <div className="coin"
|
|
draggable onDragStart={(e) => this.onDragStart(e, 'I' + i)}
|
|
style={{
|
|
backgroundColor: this.color[this.state.coin], backgroundClip: "content-box",
|
|
opacity: "0.7", border: "solid 3px " + this.color[this.state.coin]
|
|
}}>
|
|
</div>
|
|
: <div className="coin"
|
|
style={{ backgroundColor: "#f0f0f0", opacity: "0.7", border: "solid 3px grey" }}>
|
|
</div>
|
|
}
|
|
{this.state.status === 0
|
|
? <div className="card" style={{ backgroundImage: "url('FC.svg')", backgroundSize: "100%" }}
|
|
ref={(component) => { this.hand[i] = component; }} >
|
|
</div>
|
|
: null
|
|
}
|
|
</div>)
|
|
}
|
|
|
|
return (
|
|
<div className="flexCol">
|
|
<div className="flexRow flexSpace msg">
|
|
<div className="flexRow" onClick={this.leave.bind(this)}>
|
|
<img src={retImg} />return
|
|
</div>
|
|
<div style={{ color: this.color[this.state.atr] }}>
|
|
{this.state.msg}
|
|
</div>
|
|
<div className="flexRow">
|
|
<SerStats />
|
|
<img src={this.state.noise ? bp1Img : bp2Img}
|
|
onClick={(e) => this.setState({ noise: !this.state.noise })}
|
|
style={{ width: "16px", height: "16px", margin: "2px 7px" }} />
|
|
</div>
|
|
</div>
|
|
<div className="flexRow">
|
|
<Players players={this.state.players} turn={this.state.turn} live={this.state.live} />
|
|
<div id="board" className={this.state.myturn ? "flash" : ""}>
|
|
{dec}
|
|
</div>
|
|
{this.state.status === 1
|
|
? <WinStats newgame={this.newgame.bind(this)} game={this.props.game} />
|
|
: <div className="flexCol" style={{ marginTop: "8px" }}>
|
|
{hnd}
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
} |