Skip to content

Commit

Permalink
Add more actions & conditions and fix automatic login
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementPasteau committed May 21, 2024
1 parent efa5b3d commit 766c7f0
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 108 deletions.
3 changes: 1 addition & 2 deletions Extensions/BBText/bbtextruntimeobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ namespace gdjs {
*/
export class BBTextRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.OpacityHandler
{
implements gdjs.OpacityHandler {
_opacity: float;

_text: string;
Expand Down
3 changes: 1 addition & 2 deletions Extensions/BitmapText/bitmaptextruntimeobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ namespace gdjs {
*/
export class BitmapTextRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.TextContainer, gdjs.OpacityHandler, gdjs.Scalable
{
implements gdjs.TextContainer, gdjs.OpacityHandler, gdjs.Scalable {
_opacity: float;
_text: string;
/** color in format [r, g, b], where each component is in the range [0, 255] */
Expand Down
111 changes: 104 additions & 7 deletions Extensions/Multiplayer/JsExtension.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,35 @@ module.exports = {
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
.setFunctionName('gdjs.multiplayer.openLobbiesWindow');

extension
.addAction(
'ShowLobbiesWindowCloseAction',
_('Show (or hide) lobbies window close action'),
_(
'Show or hide the close button in the lobbies window. The cross is shown by default.'
),
_('Show lobbies window close action: _PARAM1_'),
'',
'JsPlatform/Extensions/multiplayer.svg',
'JsPlatform/Extensions/multiplayer.svg'
)
.addCodeOnlyParameter('currentScene', '')
.addParameter('yesorno', _('Show close button'), '', false)
.setHelpPath('/all-features/multiplayer')
.getCodeExtraInformation()
.setIncludeFile('Extensions/P2P/A_peer.js')
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
.addIncludeFile(
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
)
.addIncludeFile(
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
)
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
.setFunctionName('gdjs.multiplayer.showLobbiesCloseButton');

extension
.addAction(
'EndLobbyGame',
Expand Down Expand Up @@ -91,7 +120,7 @@ module.exports = {
'SendMessage',
_('Send custom message to other players'),
_(
"Send a custom message to other players in the lobby, with an automatic retry system if it hasn't been received. Use with the condition 'Message has been received' to know when the message has been properly processed by the server."
"Send a custom message to other players in the lobby, with an automatic retry system if it hasn't been received. Use with the condition 'Message has been received' to know when the message has been properly processed by the host."
),
_('Send message _PARAM0_ to other players with content _PARAM1_'),
'',
Expand Down Expand Up @@ -164,6 +193,30 @@ module.exports = {
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
.setFunctionName('gdjs.multiplayer.hasGameJustStarted');

extension
.addCondition(
'IsGameRunning',
_('Lobby game is running'),
_('Check if the lobby game is running.'),
_('Lobby game is running'),
'',
'JsPlatform/Extensions/multiplayer.svg',
'JsPlatform/Extensions/multiplayer.svg'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/P2P/A_peer.js')
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
.addIncludeFile(
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
)
.addIncludeFile(
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
)
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
.setFunctionName('gdjs.multiplayer.isGameRunning');

extension
.addCondition(
'HasGameJustEnded',
Expand Down Expand Up @@ -241,10 +294,10 @@ module.exports = {

extension
.addCondition(
'isPlayerServer',
_('Player is server'),
_('Check if the player is the server. (Player 1 is the server)'),
_('Player is server'),
'isPlayerHost',
_('Player is host'),
_('Check if the player is the host. (Player 1 is the host)'),
_('Player is host'),
'',
'JsPlatform/Extensions/multiplayer.svg',
'JsPlatform/Extensions/multiplayer.svg'
Expand All @@ -261,7 +314,7 @@ module.exports = {
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
.setFunctionName('gdjs.multiplayer.isPlayerServer');
.setFunctionName('gdjs.multiplayer.isPlayerHost');

extension
.addStrExpression(
Expand Down Expand Up @@ -460,12 +513,56 @@ module.exports = {
.setFunctionName('setPlayerObjectOwnership')
.setGetter('getPlayerObjectOwnership');

behavior
.addScopedCondition(
'IsObjectOwnedByCurrentPlayer',
_('Is object owned by current player'),
_(
'Check if the object is owned by the current player, as a player or the host.'
),
_('Object _PARAM0_ is owned by current player'),
'',
'JsPlatform/Extensions/multiplayer.svg',
'JsPlatform/Extensions/multiplayer.svg'
)
.addParameter('object', _('Object'), '', false)
.addParameter(
'behavior',
_('Behavior'),
'MultiplayerObjectBehavior',
false
)
.markAsAdvanced()
.setFunctionName('isObjectOwnedByCurrentPlayer');

behavior
.addScopedAction(
'TakeObjectOwnership',
_('Take ownership of object'),
_(
'Take the ownership of the object. It will then be synchronized to other players, with the current player as the owner.'
),
_('Take ownership of _PARAM0_'),
'',
'JsPlatform/Extensions/multiplayer.svg',
'JsPlatform/Extensions/multiplayer.svg'
)
.addParameter('object', _('Object'), '', false)
.addParameter(
'behavior',
_('Behavior'),
'MultiplayerObjectBehavior',
false
)
.markAsAdvanced()
.setFunctionName('takeObjectOwnership');

behavior
.addScopedAction(
'RemoveObjectOwnership',
_('Remove object ownership'),
_(
'Remove the ownership of the object from the player. It will still be synchronized to other players, but the server owns it.'
'Remove the ownership of the object from the player. It will still be synchronized to other players, but the host owns it.'
),
_('Remove ownership of _PARAM0_'),
'',
Expand Down
41 changes: 19 additions & 22 deletions Extensions/Multiplayer/messageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ namespace gdjs {
maxNumberOfRetries?: number;
messageRetryTime?: number;
}) => {
if (!gdjs.multiplayer.isGameRunning) {
if (!gdjs.multiplayer.isGameRunning()) {
// This can happen if objects are destroyed at the end of the scene.
// We should not add expected messages in this case.
return;
Expand Down Expand Up @@ -418,17 +418,14 @@ namespace gdjs {
const currentPlayerObjectOwnership = behavior.getPlayerObjectOwnership();
// Change is coherent if:
const ownershipChangeIsCoherent =
// the object is changing ownership from the same owner the server knew about,
// the object is changing ownership from the same owner the host knew about,
currentPlayerObjectOwnership === previousOwner ||
// the object is already owned by the new owner. (may have been changed by another player faster)
currentPlayerObjectOwnership === newOwner;
if (
gdjs.multiplayer.isPlayerServer() &&
!ownershipChangeIsCoherent
) {
if (gdjs.multiplayer.isPlayerHost() && !ownershipChangeIsCoherent) {
// We received an ownership change message for an object which is in an unexpected state.
// There may be some lag, and multiple ownership changes may have been sent by the other players.
// As the server, let's not change the ownership and let the player revert it.
// As the host, let's not change the ownership and let the player revert it.
logger.warn(
`Object ${objectName} with instance network ID ${instanceNetworkId} does not have the expected owner. Wanted to change from ${previousOwner} to ${newOwner}, but object has owner ${currentPlayerObjectOwnership}.`
);
Expand All @@ -451,10 +448,10 @@ namespace gdjs {
// Once the object ownership has changed, we need to acknowledge it to the player who sent this message.
sendDataTo(messageSender, ownerChangedMessageName, {});

// If we are the server,
// If we are the host,
// so we need to relay the ownership change to others,
// and expect an acknowledgment from them.
if (gdjs.multiplayer.isPlayerServer()) {
if (gdjs.multiplayer.isPlayerHost()) {
const connectedPeerIds = gdjs.evtTools.p2p.getAllPeers();
// We don't need to send the message to the player who sent the ownership change message.
const otherPeerIds = connectedPeerIds.filter(
Expand All @@ -470,7 +467,7 @@ namespace gdjs {
originalData: data,
expectedMessageName: ownerChangedMessageName,
otherPeerIds,
// As we are the server, we do not cancel the message if it times out.
// As we are the host, we do not cancel the message if it times out.
shouldCancelMessageIfTimesOut: false,
});
for (const peerId of otherPeerIds) {
Expand Down Expand Up @@ -605,9 +602,9 @@ namespace gdjs {
instanceNetworkId
] = messageInstanceClock;

// If we are are the server,
// If we are are the host,
// we need to relay the position to others except the player who sent the update message.
if (gdjs.multiplayer.isPlayerServer()) {
if (gdjs.multiplayer.isPlayerHost()) {
const connectedPeerIds = gdjs.evtTools.p2p.getAllPeers();
// We don't need to send the message to the player who sent the update message.
for (const peerId of connectedPeerIds) {
Expand Down Expand Up @@ -935,9 +932,9 @@ namespace gdjs {
// Once the object is destroyed, we need to acknowledge it to the player who sent the destroy message.
sendDataTo(messageSender, destroyedMessageName, {});

// If we are the server, we need to relay the destruction to others.
// If we are the host, we need to relay the destruction to others.
// And expect an acknowledgment from everyone else as well.
if (gdjs.multiplayer.isPlayerServer()) {
if (gdjs.multiplayer.isPlayerHost()) {
const connectedPeerIds = gdjs.evtTools.p2p.getAllPeers();
// We don't need to send the message to the player who sent the destroy message.
const otherPeerIds = connectedPeerIds.filter(
Expand Down Expand Up @@ -1016,9 +1013,9 @@ namespace gdjs {
sendDataTo(peerId, messageName, messageData);
}

// If we are the server, we can consider this messaged as received
// If we are the host, we can consider this messaged as received
// and add it to the list of custom messages to process on top of the messages received.
if (gdjs.multiplayer.isPlayerServer()) {
if (gdjs.multiplayer.isPlayerHost()) {
const message = gdjs.evtTools.p2p.getEvent(messageName);
message.pushData(
new gdjs.evtTools.p2p.EventData(
Expand Down Expand Up @@ -1119,9 +1116,9 @@ namespace gdjs {
);
sendDataTo(messageSender, acknowledgmentMessageName, {});

// If we are the server,
// If we are the host,
// so we need to relay the message to others.
if (gdjs.multiplayer.isPlayerServer()) {
if (gdjs.multiplayer.isPlayerHost()) {
// In the case of custom messages, we relay the message to all players, including the sender.
// This allows the sender to process it the same way others would, when they receive the event.
const connectedPeerIds = gdjs.evtTools.p2p.getAllPeers();
Expand Down Expand Up @@ -1186,8 +1183,8 @@ namespace gdjs {
const handleUpdateSceneMessages = (
runtimeScene: gdjs.RuntimeScene
): void => {
// Only the server synchronizes the scene state.
if (!gdjs.multiplayer.isPlayerServer()) {
// Only the host synchronizes the scene state.
if (!gdjs.multiplayer.isPlayerHost()) {
return;
}
const sceneNetworkSyncData = runtimeScene.getNetworkSyncData();
Expand Down Expand Up @@ -1285,8 +1282,8 @@ namespace gdjs {
const handleUpdateGameMessages = (
runtimeScene: gdjs.RuntimeScene
): void => {
// Only the server synchronizes the global state.
if (!gdjs.multiplayer.isPlayerServer()) {
// Only the host synchronizes the global state.
if (!gdjs.multiplayer.isPlayerHost()) {
return;
}
const gameNetworkSyncData = runtimeScene.getGame().getNetworkSyncData();
Expand Down
29 changes: 26 additions & 3 deletions Extensions/Multiplayer/multiplayercomponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace gdjs {
const lobbiesIframeContainerId = 'lobbies-iframe-container';
const lobbiesIframeId = 'lobbies-iframe';

let canLobbyBeClosed = true;

export const getDomElementContainer = (
runtimeScene: gdjs.RuntimeScene
): HTMLDivElement | null => {
Expand Down Expand Up @@ -167,6 +169,10 @@ namespace gdjs {
);
_closeContainer.appendChild(_close);

if (!canLobbyBeClosed) {
_closeContainer.style.visibility = 'hidden';
}

const loaderContainer: HTMLDivElement = document.createElement('div');
loaderContainer.id = lobbiesLoaderContainerId;
loaderContainer.style.display = 'flex';
Expand Down Expand Up @@ -349,20 +355,37 @@ namespace gdjs {
rootContainer.remove();
};

export const hideLobbiesCloseArrow = function (
export const changeLobbiesWindowCloseActionVisibility = function (
runtimeScene: gdjs.RuntimeScene,
canClose: boolean
) {
canLobbyBeClosed = canClose;

const closeContainer = getLobbiesCloseContainer(runtimeScene);
if (!closeContainer) {
return;
}

closeContainer.style.visibility = canClose ? 'inherit' : 'hidden';
};

export const hideLobbiesCloseButtonTemporarily = function (
runtimeScene: gdjs.RuntimeScene
) {
if (!canLobbyBeClosed) return;

const closeContainer = getLobbiesCloseContainer(runtimeScene);
if (!closeContainer) {
return;
}

closeContainer.style.display = 'none';
closeContainer.style.visibility = 'hidden';

// There is a risk a player leaves the lobby before the end of the countdown,
// so we show the close container again after 5 seconds in case this happens,
// to allow the player to leave the lobby.
setTimeout(() => {
closeContainer.style.display = 'flex';
closeContainer.style.visibility = 'inherit';
}, 5000);
};

Expand Down
Loading

0 comments on commit 766c7f0

Please sign in to comment.