@@ -3,6 +3,7 @@
|
||||
namespace Mine\SeekerBundle\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class GameController extends Controller
|
||||
{
|
||||
@@ -11,10 +12,11 @@ class GameController extends Controller
|
||||
return $this->render('MineSeekerBundle:Game:index.html.twig');
|
||||
}
|
||||
|
||||
public function playAction()
|
||||
public function playAction(Request $request)
|
||||
{
|
||||
return $this->render('MineSeekerBundle:Game:play.html.twig', array(
|
||||
'env' => $this->container->getParameter('kernel.environment')
|
||||
'env' => $this->container->getParameter('kernel.environment'),
|
||||
'ssl' => $request->isSecure() ? 'true' : 'false'
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,13 @@ class Gamer
|
||||
*/
|
||||
private $userAgent;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(name="conn_timestamp", type="datetime", nullable=false)
|
||||
*/
|
||||
private $connTimestamp;
|
||||
|
||||
|
||||
/**
|
||||
* Get id
|
||||
@@ -180,4 +187,28 @@ class Gamer
|
||||
{
|
||||
return $this->userAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connTimestamp
|
||||
*
|
||||
* @param \DateTime $connTimestamp
|
||||
*
|
||||
* @return Gamer
|
||||
*/
|
||||
public function setConnTimestamp($connTimestamp)
|
||||
{
|
||||
$this->connTimestamp = $connTimestamp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connTimestamp
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getConnTimestamp()
|
||||
{
|
||||
return $this->connTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,13 @@ class Gamer
|
||||
*/
|
||||
private $userAgent;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(name="conn_timestamp", type="datetime", nullable=false)
|
||||
*/
|
||||
private $connTimestamp;
|
||||
|
||||
|
||||
/**
|
||||
* Get id
|
||||
|
||||
@@ -405,4 +405,28 @@ class PlayedGame
|
||||
{
|
||||
return $this->step;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resign
|
||||
*
|
||||
* @param string $resign
|
||||
*
|
||||
* @return PlayedGame
|
||||
*/
|
||||
public function setResign($resign)
|
||||
{
|
||||
$this->resign = $resign;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resign
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getResign()
|
||||
{
|
||||
return $this->resign;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import MineSeeker from './mine-seeker/app';
|
||||
|
||||
ReactDOM.render(
|
||||
<MineSeeker env={document.getElementById('mine-wrapper').dataset.env}
|
||||
gameId={document.getElementById('mine-wrapper').dataset.gameId}/>,
|
||||
gameId={document.getElementById('mine-wrapper').dataset.gameId}
|
||||
ssl={document.getElementById('mine-wrapper').dataset.ssl}/>,
|
||||
document.getElementById('mine-wrapper')
|
||||
);
|
||||
|
||||
@@ -11,13 +11,15 @@ class MineSeeker extends React.Component {
|
||||
|
||||
this.state = {
|
||||
env: props.env,
|
||||
ssl: props.ssl,
|
||||
gameInherited: props.gameId !== '',
|
||||
gameAssoc: gameAssoc,
|
||||
channel: channel,
|
||||
session: null,
|
||||
createGrid: false,
|
||||
stepCache: [],
|
||||
disconnect: false
|
||||
connectionLost: false,
|
||||
end: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +32,12 @@ class MineSeeker extends React.Component {
|
||||
return text;
|
||||
}
|
||||
|
||||
/** STEP */
|
||||
/**
|
||||
* STEP
|
||||
*
|
||||
* @param coords
|
||||
* @returns {{red: *, blue: *}}
|
||||
*/
|
||||
makePointsCalcAndStep(coords) {
|
||||
let users = this.refs.gridControl.refs.userControl,
|
||||
activePlayer = users.state.activePlayer ? 'blue' : 'red',
|
||||
@@ -51,7 +58,38 @@ class MineSeeker extends React.Component {
|
||||
return {red: redPoints, blue: bluePoints};
|
||||
}
|
||||
|
||||
/** THE END */
|
||||
/**
|
||||
* START
|
||||
*
|
||||
* @param payload
|
||||
*/
|
||||
makeGameStart(payload) {
|
||||
/** every time the blue starts */
|
||||
this.refs.gridControl.refs.userControl.setState({activePlayer: 1});
|
||||
|
||||
/** Set up player names w/ server data */
|
||||
this.refs.gridControl.refs.userControl.refs.red.setState({
|
||||
name: payload.users.red !== '' ? payload.users.red : payload.users.redAnon,
|
||||
});
|
||||
|
||||
this.refs.gridControl.refs.userControl.refs.blue.setState({
|
||||
name: payload.users.blue !== '' ? payload.users.blue : payload.users.blueAnon,
|
||||
desc: this.refs.gridControl.state.webPlayer === 'blue'
|
||||
? this.refs.gridControl.state.desc.you
|
||||
: this.refs.gridControl.state.desc.buddy,
|
||||
active: true,
|
||||
});
|
||||
|
||||
this.refs.gridControl.setState({overlay: false});
|
||||
}
|
||||
|
||||
/**
|
||||
* THE END
|
||||
*
|
||||
* @param bluePoints
|
||||
* @param redPoints
|
||||
* @param resign
|
||||
*/
|
||||
makeGameEndIfItEnds(bluePoints, redPoints, resign = false) {
|
||||
let redWins = redPoints > 25,
|
||||
blueWins = bluePoints > 25;
|
||||
@@ -86,10 +124,13 @@ class MineSeeker extends React.Component {
|
||||
: "You WIN!"
|
||||
});
|
||||
|
||||
this.setState({end: true});
|
||||
|
||||
this.makeGameEndIfItEnds(0, 0, true);
|
||||
}
|
||||
|
||||
clickResign() {
|
||||
/** PUBLISH */
|
||||
this.state.session.publish(this.state.channel, {
|
||||
'resign': this.refs.gridControl.refs.userControl.state.activePlayer ? 'blue' : 'red'
|
||||
});
|
||||
@@ -119,13 +160,13 @@ class MineSeeker extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
wInit(session, gridServer, gridClient) {
|
||||
wInit(session, data, gridClient) {
|
||||
this.setState({session: session});
|
||||
|
||||
/** save session to GridControl */
|
||||
/** render grid fields - #12 */
|
||||
this.refs.gridControl.setState({
|
||||
grid: this.state.gameInherited ? JSON.parse(Base64.decode(gridServer)) : gridClient,
|
||||
grid: this.state.gameInherited ? JSON.parse(Base64.decode(data))['grid'] : gridClient,
|
||||
channel: this.state.channel,
|
||||
desc: {
|
||||
buddy: <div>
|
||||
@@ -157,39 +198,31 @@ class MineSeeker extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
wSubscribe(payload) {
|
||||
wSubscribe(payload, rpcUsers = null) {
|
||||
this.state.env === 'dev' && console.info(
|
||||
(typeof payload.user !== 'undefined' ? payload.user : 'user') + " has been subscribed to the channel!"
|
||||
);
|
||||
|
||||
if (!this.state.disconnect) {
|
||||
/** setup the web player */
|
||||
null === this.refs.gridControl.state.webPlayer && this.refs.gridControl.setState({
|
||||
webPlayer: payload.user === payload.users.blue || payload.user === payload.users.blueAnon
|
||||
? 'blue'
|
||||
: 'red'
|
||||
let firstUser = !rpcUsers;
|
||||
|
||||
this.refs.gridControl.state.webPlayer === null && this.refs.gridControl.setState({
|
||||
webPlayer: payload.user === payload.users.blue ||
|
||||
(
|
||||
firstUser && payload.users.blueAnon !== '' ||
|
||||
!firstUser && (rpcUsers.blueAnon === '' && rpcUsers.blue === '')
|
||||
)
|
||||
? 'blue' : 'red'
|
||||
});
|
||||
|
||||
/** every user has been came */
|
||||
if (payload.userCnt === 2) {
|
||||
/** every time the blue starts */
|
||||
this.refs.gridControl.refs.userControl.setState({activePlayer: 1});
|
||||
|
||||
/** Set up player names w/ server data */
|
||||
this.refs.gridControl.refs.userControl.refs.red.setState({
|
||||
name: payload.users.red !== '' ? payload.users.red : payload.users.redAnon,
|
||||
});
|
||||
|
||||
this.refs.gridControl.refs.userControl.refs.blue.setState({
|
||||
name: payload.users.blue !== '' ? payload.users.blue : payload.users.blueAnon,
|
||||
desc: this.refs.gridControl.state.webPlayer === 'blue'
|
||||
? this.refs.gridControl.state.desc.you
|
||||
: this.refs.gridControl.state.desc.buddy,
|
||||
active: true,
|
||||
});
|
||||
|
||||
this.refs.gridControl.setState({overlay: false});
|
||||
}
|
||||
if (
|
||||
payload.userCnt === 2 &&
|
||||
(
|
||||
!this.state.connectionLost ||
|
||||
this.state.connectionLost && false === this.refs.gridControl.refs.userControl.state.activePlayer && !this.state.end
|
||||
)
|
||||
) {
|
||||
this.makeGameStart(payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +259,7 @@ class MineSeeker extends React.Component {
|
||||
}
|
||||
|
||||
/** Connect - Subscribe */
|
||||
subscribe() {
|
||||
subscribe(rpcUsers = null) {
|
||||
this.state.session.subscribe(
|
||||
this.state.channel,
|
||||
(uri, payload, log) => {
|
||||
@@ -238,30 +271,31 @@ class MineSeeker extends React.Component {
|
||||
this.wTopic(payload);
|
||||
} else {
|
||||
if (isNotUnsubscribe) {
|
||||
this.wSubscribe(payload);
|
||||
this.wSubscribe(payload, rpcUsers);
|
||||
} else {
|
||||
this.wUnsubscribe(payload);
|
||||
}
|
||||
}
|
||||
|
||||
/** RECONNECTION */
|
||||
if (payload.userCnt === 2 && this.state.disconnect) {
|
||||
if (payload.userCnt === 2 && this.state.connectionLost) {
|
||||
this.state.env === 'dev' && console.info('Reconnection process');
|
||||
|
||||
/** PUBLISH */
|
||||
let cache = this.state.stepCache;
|
||||
cache.forEach((item) => this.state.session.publish(this.state.channel, item));
|
||||
this.setState({disconnect: false, stepCache: []});
|
||||
this.setState({connectionLost: false, stepCache: []});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** after rendering */
|
||||
/** After rendering */
|
||||
componentDidMount() {
|
||||
/** Create Websocket w/ Bahnhof.js */
|
||||
let websocket = WS.connect(
|
||||
this.state.env === 'dev'
|
||||
? "ws://mine.dev:6450"
|
||||
: "ws://www.mineseeker.ninja:6450"
|
||||
: (this.state.ssl === 'true' ? "wss" : "ws") + "://www.mineseeker.ninja:6450"
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -271,7 +305,7 @@ class MineSeeker extends React.Component {
|
||||
websocket.on("socket/connect", (session) => {
|
||||
this.state.env === 'dev' && console.info("Successfully connected to the Server!");
|
||||
|
||||
if (!this.state.disconnect) {
|
||||
if (!this.state.connectionLost) {
|
||||
let gridClient = this.state.gameInherited || new Grid().state.grid;
|
||||
|
||||
/**
|
||||
@@ -284,11 +318,11 @@ class MineSeeker extends React.Component {
|
||||
this.state.gameInherited ? this.state.gameAssoc : [Base64.encode(JSON.stringify(gridClient)), this.state.gameAssoc]
|
||||
)
|
||||
.then(
|
||||
(gridServer) => {
|
||||
this.state.env === 'dev' && console.info("Grid has been created! Return w/ gameAssoc.");
|
||||
(data) => {
|
||||
this.state.env === 'dev' && console.info('RPC has been called');
|
||||
|
||||
this.wInit(session, gridServer, gridClient);
|
||||
this.subscribe();
|
||||
this.wInit(session, data, gridClient);
|
||||
this.subscribe(this.state.gameInherited && JSON.parse(Base64.decode(data))['users']);
|
||||
},
|
||||
(error, desc) => this.state.env === 'dev' && console.error(["RPC Error", error, desc])
|
||||
);
|
||||
@@ -304,7 +338,11 @@ class MineSeeker extends React.Component {
|
||||
*/
|
||||
websocket.on("socket/disconnect", (error) => {
|
||||
this.state.env === 'dev' && console.error("Disconnected for " + error.reason + " with code " + error.code);
|
||||
this.setState({disconnect: true});
|
||||
|
||||
error.code === 6 && this.setState({connectionLost: true});
|
||||
error.code === 3 && setTimeout(function () {
|
||||
this.componentDidMount();
|
||||
}.bind(this), 500);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -344,7 +382,7 @@ class MineSeeker extends React.Component {
|
||||
};
|
||||
|
||||
/** PUBLISH */
|
||||
!this.state.disconnect
|
||||
!this.state.connectionLost
|
||||
? this.state.session.publish(this.state.channel, dataPack)
|
||||
: this.cachePublish(dataPack);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{% block header %}
|
||||
<h1>MineSeeker</h1>
|
||||
<h3>version 1.0a</h3>
|
||||
<h3>version 1.1.3a</h3>
|
||||
<a href="{{ path('MineSeekerBundle_gamePlay') }}">Play now</a>
|
||||
<img src="{{ asset('bundles/mineseeker/images/homepage/mineseeker-2.png') }}" alt="" border="0">
|
||||
{% endblock %}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<div class="mine-container">
|
||||
<div id="mine-wrapper"
|
||||
data-env="{{ env }}"
|
||||
data-ssl="{{ ssl }}"
|
||||
data-game-id="{{ app.request.get('gameAssoc') }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -56,7 +56,12 @@ class MineseekerRpc implements RpcInterface
|
||||
*/
|
||||
public function connectGame(ConnectionInterface $connection, WampRequest $request, array $params)
|
||||
{
|
||||
return base64_encode(json_encode($this->getGrid($params)));
|
||||
return base64_encode(json_encode(
|
||||
array(
|
||||
'grid' => $this->getGrid($params),
|
||||
'users' => $this->getUsers($params)
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +87,36 @@ class MineseekerRpc implements RpcInterface
|
||||
return $getsee;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $gameAssoc
|
||||
* @return array
|
||||
*/
|
||||
private function getUsers($gameAssoc)
|
||||
{
|
||||
$this->reConnect();
|
||||
return $this->getUserCollection(
|
||||
$this->em
|
||||
->getRepository('MineSeekerBundle:PlayedGame')
|
||||
->findOneByGameAssoc($gameAssoc)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user collection from PlayedGame entity
|
||||
*
|
||||
* @param $playedGame
|
||||
* @return array
|
||||
*/
|
||||
private function getUserCollection($playedGame)
|
||||
{
|
||||
return array(
|
||||
'red' => null !== $playedGame->getRed() ? $playedGame->getRed()->getUsername() : '',
|
||||
'blue' => null !== $playedGame->getBlue() ? $playedGame->getBlue()->getUsername() : '',
|
||||
'redAnon' => null !== $playedGame->getRedAnon() ? $playedGame->getRedAnon()->getUserName() : '',
|
||||
'blueAnon' => null !== $playedGame->getBlueAnon() ? $playedGame->getBlueAnon()->getUserName() : ''
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return boolean
|
||||
|
||||
@@ -194,14 +194,17 @@ class MineseekerTopic implements TopicInterface
|
||||
->getRepository('MineSeekerBundle:PlayedGame')
|
||||
->findOneByGameAssoc($gameAssoc);
|
||||
|
||||
/** @var $users {array} */
|
||||
$users = $this->getUserCollection($playedGame);
|
||||
|
||||
$red = "" !== $users['red'] || "" !== $users['redAnon'] ? 1 : 0;
|
||||
$blue = "" !== $users['blue'] || "" !== $users['blueAnon'] ? 1 : 0;
|
||||
$one = $topic->count() === 1;
|
||||
$two = $topic->count() === 2;
|
||||
|
||||
/** This checks it is a reconnection */
|
||||
if (
|
||||
(null !== $users['red'] || null !== $users['redAnon']) &&
|
||||
(null !== $users['blue'] || null !== $users['blueAnon'])
|
||||
) {
|
||||
/** @var $users array Save users to database */
|
||||
if (($one && ($red + $blue === 0)) || ($two && ($red + $blue === 1))) {
|
||||
/** @var $users {array} w/ save users to database */
|
||||
$users = $this->saveUserToDb($topic, $userName, $user, $topic->count());
|
||||
}
|
||||
|
||||
@@ -226,6 +229,7 @@ class MineseekerTopic implements TopicInterface
|
||||
->getRepository('MineSeekerBundle:PlayedGame')
|
||||
->findOneByGameAssoc($gameAssoc);
|
||||
|
||||
/** the user is not anonym */
|
||||
if (!is_string($user)) {
|
||||
$FOSUser = $this->em
|
||||
->getRepository('JotunheimrUserBundle:User')
|
||||
@@ -234,7 +238,6 @@ class MineseekerTopic implements TopicInterface
|
||||
if ($count == 1) {
|
||||
/** @var $random {integer} Active player: red: 0, blue: 1 */
|
||||
$random = rand(0, 1);
|
||||
|
||||
!$random ? $playedGame->setRed($FOSUser) : $playedGame->setBlue($FOSUser);
|
||||
} else {
|
||||
null === $playedGame->getRed() && null === $playedGame->getRedAnon()
|
||||
@@ -246,12 +249,12 @@ class MineseekerTopic implements TopicInterface
|
||||
|
||||
$anon = new Gamer();
|
||||
$anon->setUserName($userName);
|
||||
$anon->setConnTimestamp(new \DateTime());
|
||||
$this->em->persist($anon);
|
||||
|
||||
if ($count == 1) {
|
||||
/** @var $random {integer} Active player: red: 0, blue: 1 */
|
||||
$random = rand(0, 1);
|
||||
|
||||
!$random ? $playedGame->setRedAnon($anon) : $playedGame->setBlueAnon($anon);
|
||||
} else {
|
||||
null === $playedGame->getRed() && null === $playedGame->getRedAnon()
|
||||
|
||||
Reference in New Issue
Block a user