So, I’ve managed to create a custom module with custom logic and a custom state.
I’ve managed to make a client create a match via the rpc function with the server sending back the match id to the client and the client using that match id to join the match.
Now I have trouble exchanging message between the client and the server regarding the opcode and the match state.
In unity, the client does this :
//We create a match against a bot.
public async void PairImpairPvBCreateMatch()
{
string clientAsks = "We ask to create a match against a bot";
string jsonFromClient = JsonUtility.ToJson(clientAsks);
var payload = jsonFromClient;
var rpcid = "pairimpairpvbcreatematch";
var serverResponse = await client.RpcAsync(session, rpcid, payload);
var serverResponsePayload = serverResponse.Payload;
MatchID serverResponseMatchId = JsonUtility.FromJson<MatchID>(serverResponsePayload);
matchID = serverResponseMatchId.match_id;
PairImpairPvBJoinMatch(); //We then join that match.
Debug.Log("Match ID is : " + serverResponseMatchId.match_id); ; // Works
}
//Join a match against a bot. Works
public async void PairImpairPvBJoinMatch()
{
var matchId = matchID;
var match = await socket.JoinMatchAsync(matchId);
foreach (var presence in match.Presences)
{
Debug.LogFormat("User id '{0}' name '{1}'.", presence.UserId, presence.Username);
}
socket.ReceivedMatchState += OnReceiveMatchState; // We sub to the receive match state.
PairImpairPvBAskForFirstPlayerToPlay();
}
public async void PairImpairPvBAskForFirstPlayerToPlay()
{
Debug.Log("We are sending a message to the server"); //Appears in unity console.
var matchId = matchID;
var opCode = 1;
await socket.SendMatchStateAsync(matchId, opCode, ""); // State is null.
}
private async void OnReceiveMatchState(IMatchState matchState) //Nothing is received back.
{
Debug.Log("We received a message back from the server, can we understand it ?");
switch (pairImpairPvBOpCodes)
{
case PairImpairPvBOpCodes.GAMEISSTARTING:
Debug.Log("Server said game is starting, we understood that message");
await socket.SendMatchStateAsync(matchID, 1, "");
break;
}
On the server, the messages are supposed to be received in the matchloop function, I kept the one I found on github and modified its state to fit the game needs but the following for loop does not seems to receive anything :
let matchLoop: nkruntime.MatchLoopFunction = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, messages: nkruntime.MatchMessage[]) {
var s = state as PairImpairPvBState;
logger.debug('Running match loop. Tick: %d', tick);
if (Object.keys(s.presences).length + s.joinsInProgress === 0) {
s.emptyTicks++;
if (s.emptyTicks >= maxEmptySec * tickRate) {
// Match has been empty for too long, close it.
logger.info('closing idle match');
return null;
}
}
let t = msecToSec(Date.now());
// If there's no game in progress check if we can (and should) start one!
if (!s.playing) {
// Between games any disconnected users are purged, there's no in-progress game for them to return to anyway.
for (let userID in s.presences) {
if (s.presences[userID] === null) {
delete s.presences[userID];
}
}
// Check if we need to update the label so the match now advertises itself as open to join. ATTENTION ICI ON GARDE EN DESSOUS DE 1 PCK C'EST CONTRE UN BOT !!
if (Object.keys(s.presences).length < 1 && s.label.open != 1) {
s.label.open = 1;
let labelJSON = JSON.stringify(s.label);
dispatcher.matchLabelUpdate(labelJSON);
}
// Check if we have enough players to start a game.
if (Object.keys(s.presences).length < 1) {
return { state: s };
}
/* // Check if enough time has passed since the last game.
if (s.nextGameRemainingTicks > 0) {
s.nextGameRemainingTicks--
return { state: s };
}*/
// We can start a game! Set up the game state and assign the marks to each player.
s.playing = true;
return {state: s};
}
// There's a game in progress. Check for input, update match state, and send messages to clients.
for (const message of messages)
{
logger.debug('A MESSAGE IS RECEIVED FROM USER '); // This does not appear, meaning server does not receive message from client ?
switch (message.opCode)
{
case PairImpairPvBOpCode.GAMEISSTARTING:
logger.debug('Received starting from user: %v'); // This does not appear, meaning server does not receive message from client ?
getRandomPlayerBotStart(logger,state,dispatcher);
break;
case PairImpairPvBOpCode.BOTTURNTOPLAY:
botSelectsBilles(state);
break;
case PairImpairPvBOpCode.PLAYERTURNTOPLAY:
playerTurnToPlay(state,dispatcher);
break;
case PairImpairPvBOpCode.PLAYERSELECTEDBILLES:
//On recoit la selection du joueur et on check après s'il est parieur ou pas.
let msg = {} as PairImpairPvBPlayerBillesSelected;
msg=JSON.parse(nk.binaryToString(message.data));
s.playerBillesPariees=msg.playerBillesSelected;
playerBillesSelection(state);
break;
case PairImpairPvBOpCode.BOTISPARIEUR:
botEvenSelection(state);
break;
case PairImpairPvBOpCode.PLAYERISPARIEUR:
playerShowParieurCanvas(dispatcher);
let playerEvenChoice = {} as PairImpairPvBPlayerEvenChoice;
playerEvenChoice=JSON.parse(nk.binaryToString(message.data));
s.playerEvenChoice=playerEvenChoice.playerEvenChoice;
break;
case PairImpairPvBOpCode.CHECKWHOWONTURN:
CheckWhoHasWonTurn(state);
break;
case PairImpairPvBOpCode.CHECKIFPLAYERWONTURN:
CheckIfPlayerWonTurn(state);
break;
case PairImpairPvBOpCode.CHECKIFBOTWONTURN:
CheckIfBotWonTurn(state);
break;
case PairImpairPvBOpCode.BOTWINSTURN:
//Set scores and billes, send message to client, check turn
BotWonTurn(state,dispatcher);
break;
case PairImpairPvBOpCode.BOTLOOSESTURN:
//Set scores and billes, send message to client, check turn
BotLostTurn(state,dispatcher);
break;
case PairImpairPvBOpCode.PLAYERWINSTURN:
//Set scores and billes, send message to client, check turn
PlayerWonTurn(state,dispatcher);
break;
case PairImpairPvBOpCode.PLAYERLOOSESTURN:
//Set scores and billes, send message to client, check turn
PlayerLostTurn(state,dispatcher);
break;
case PairImpairPvBOpCode.CHECKTURN:
CheckForTurn(state);
break;
case PairImpairPvBOpCode.STARTNEWTURN:
CheckForNextPlayerToPlay(logger,state)
break;
case PairImpairPvBOpCode.CHECKWHOWONMANCHE:
CheckForMancheWinner(state);
break;
case PairImpairPvBOpCode.BOTWINSMANCHE:
//Set score , send client message and check manche
BotWinsManche(state,dispatcher);
break;
case PairImpairPvBOpCode.PLAYERWINSMANCHE:
//Set score , send client message and check manche
PlayerWinsManche(state,dispatcher);
break;
case PairImpairPvBOpCode.EQUALITYWINMANCHE:
//Set score , send client message and check manche
EqualityWinsManche(state,dispatcher);
break;
case PairImpairPvBOpCode.CHECKMANCHE:
CheckForManche(state);
break;
case PairImpairPvBOpCode.STARTNEWMANCHE:
CheckWhoStartNewManche(state,dispatcher);
break;
case PairImpairPvBOpCode.CHECKFORGAMEWINNER:
CheckWhoWonGame(state);
break;
case PairImpairPvBOpCode.BOTWINSGAME:
BotWinsGame(state,dispatcher)
break;
case PairImpairPvBOpCode.PLAYERWINSGAME:
PlayerWinsGame(state,dispatcher)
break;
case PairImpairPvBOpCode.EQUALITYWINGAME:
EqualityWinsGame(state,dispatcher)
break;
case PairImpairPvBOpCode.TERMINATEMATCH:
matchTerminate;
break;
}
}
return { state: s };
}