Optionally allow observers to rejoin a game when they weren't here during the game setup.
Patch by elexis, fixes #3242. This was SVN commit r16945.
This commit is contained in:
parent
8e70140ec2
commit
e56dddbefb
@ -6,8 +6,9 @@ function getDisconnectReason(id)
|
||||
case 0: return translate("Unknown reason");
|
||||
case 1: return translate("Unexpected shutdown");
|
||||
case 2: return translate("Incorrect network protocol version");
|
||||
case 3: return translate("Game has already started");
|
||||
default: return sprintf(translate("\\[Invalid value %(id)s]"), { id: id });
|
||||
case 3: return translate("Game is loading, please try later");
|
||||
case 4: return translate("Game has already started, no observers allowed");
|
||||
default: return sprintf(translate("\\[Invalid value %(id)s]"), { "id": id });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,20 @@ function initMain()
|
||||
mapFilters.list_data = getFilterIds();
|
||||
g_GameAttributes.mapFilter = "default";
|
||||
|
||||
// For singleplayer reduce the size of more options dialog by three options (cheats, rated game, observer late join = 90px)
|
||||
if (!g_IsNetworked)
|
||||
{
|
||||
Engine.GetGUIObjectByName("moreOptions").size = "50%-200 50%-195 50%+200 50%+160";
|
||||
Engine.GetGUIObjectByName("hideMoreOptions").size = "50%-70 310 50%+70 336";
|
||||
}
|
||||
// For non-lobby multiplayergames reduce the size of the dialog by one option (rated game, 30px)
|
||||
else if (g_IsNetworked && !Engine.HasXmppClient())
|
||||
{
|
||||
Engine.GetGUIObjectByName("moreOptions").size = "50%-200 50%-195 50%+200 50%+220";
|
||||
Engine.GetGUIObjectByName("hideMoreOptions").size = "50%-70 370 50%+70 396";
|
||||
Engine.GetGUIObjectByName("optionObserverLateJoin").size = "14 338 94% 366";
|
||||
}
|
||||
|
||||
// Setup controls for host only
|
||||
if (g_IsController)
|
||||
{
|
||||
@ -255,6 +269,11 @@ function initMain()
|
||||
updateGameAttributes();
|
||||
};
|
||||
|
||||
Engine.GetGUIObjectByName("observerLateJoin").onPress = function() {
|
||||
g_GameAttributes.settings.ObserverLateJoin = this.checked;
|
||||
updateGameAttributes();
|
||||
};
|
||||
|
||||
Engine.GetGUIObjectByName("disableTreasures").onPress = function() {
|
||||
g_GameAttributes.settings.DisableTreasures = this.checked;
|
||||
updateGameAttributes();
|
||||
@ -316,6 +335,7 @@ function initMain()
|
||||
{
|
||||
Engine.GetGUIObjectByName("optionCheats").hidden = false;
|
||||
Engine.GetGUIObjectByName("enableCheats").checked = false;
|
||||
Engine.GetGUIObjectByName("optionObserverLateJoin").hidden = false;
|
||||
g_GameAttributes.settings.CheatsEnabled = false;
|
||||
// Setup ranked option if we are connected to the lobby.
|
||||
if (Engine.HasXmppClient())
|
||||
@ -331,6 +351,9 @@ function initMain()
|
||||
{
|
||||
Engine.GetGUIObjectByName("enableCheatsText").hidden = true;
|
||||
Engine.GetGUIObjectByName("enableCheats").hidden = false;
|
||||
Engine.GetGUIObjectByName("observerLateJoinText").hidden = true;
|
||||
Engine.GetGUIObjectByName("observerLateJoin").hidden = false;
|
||||
|
||||
if (Engine.HasXmppClient())
|
||||
{
|
||||
Engine.GetGUIObjectByName("enableRatingText").hidden = true;
|
||||
@ -1188,10 +1211,12 @@ function onGameAttributesChange()
|
||||
var populationCap = Engine.GetGUIObjectByName("populationCap");
|
||||
var startingResources = Engine.GetGUIObjectByName("startingResources");
|
||||
var ceasefire = Engine.GetGUIObjectByName("ceasefire");
|
||||
var observerLateJoin = Engine.GetGUIObjectByName("observerLateJoin");
|
||||
|
||||
var numPlayersText= Engine.GetGUIObjectByName("numPlayersText");
|
||||
var mapSizeDesc = Engine.GetGUIObjectByName("mapSizeDesc");
|
||||
var mapSizeText = Engine.GetGUIObjectByName("mapSizeText");
|
||||
var observerLateJoinText = Engine.GetGUIObjectByName("observerLateJoinText");
|
||||
var revealMapText = Engine.GetGUIObjectByName("revealMapText");
|
||||
var exploreMapText = Engine.GetGUIObjectByName("exploreMapText");
|
||||
var disableTreasuresText = Engine.GetGUIObjectByName("disableTreasuresText");
|
||||
@ -1222,6 +1247,10 @@ function onGameAttributesChange()
|
||||
}
|
||||
else
|
||||
enableRatingText.caption = "Unknown";
|
||||
|
||||
observerLateJoin.checked = g_GameAttributes.settings.ObserverLateJoin;
|
||||
observerLateJoinText.caption = observerLateJoin.checked ? translate("Yes") : translate("No");
|
||||
|
||||
gameSpeedText.caption = g_GameSpeeds.names[speedIdx];
|
||||
gameSpeedBox.selected = speedIdx;
|
||||
populationCap.selected = (mapSettings.PopulationCap !== undefined && POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) != -1 ? POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) : POPULATION_CAP_DEFAULTIDX);
|
||||
|
@ -270,7 +270,7 @@
|
||||
|
||||
<!-- More Options -->
|
||||
<object hidden="true" name="moreOptionsFade" type="image" z="60" sprite="ModernFade"/>
|
||||
<object name="moreOptions" type="image" sprite="ModernDialog" size="50%-200 50%-195 50%+200 50%+220" z="70" hidden="true">
|
||||
<object name="moreOptions" type="image" sprite="ModernDialog" size="50%-200 50%-195 50%+200 50%+250" z="70" hidden="true">
|
||||
<object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
|
||||
<translatableAttribute id="caption">More Options</translatableAttribute>
|
||||
</object>
|
||||
@ -385,12 +385,22 @@
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="optionObserverLateJoin" size="14 368 94% 396" hidden="true">
|
||||
<object size="0 0 40% 28" type="text" hidden="false" style="ModernRightLabelText">
|
||||
<translatableAttribute id="caption">Late Observer Joins:</translatableAttribute>
|
||||
</object>
|
||||
<object name="observerLateJoinText" size="40% 0 100% 28" type="text" style="ModernLeftLabelText"/>
|
||||
<object name="observerLateJoin" size="40%+10 5 40%+30 100%-5" type="checkbox" style="ModernTickBox" hidden="true" tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Allow observers to join after the game started.</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<!-- Hide More Options Button -->
|
||||
<object
|
||||
name="hideMoreOptions"
|
||||
type="button"
|
||||
style="StoneButton"
|
||||
size="50%-70 370 50%+70 396"
|
||||
size="50%-70 400 50%+70 426"
|
||||
tooltip_style="onscreenToolTip"
|
||||
hotkey="cancel"
|
||||
>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -62,6 +62,7 @@ enum NetDisconnectReason
|
||||
NDR_UNKNOWN = 0,
|
||||
NDR_UNEXPECTED_SHUTDOWN,
|
||||
NDR_INCORRECT_PROTOCOL_VERSION,
|
||||
NDR_SERVER_LOADING,
|
||||
NDR_SERVER_ALREADY_IN_GAME
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?'
|
||||
#define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!'
|
||||
#define PS_PROTOCOL_VERSION 0x01010006 // Arbitrary protocol
|
||||
#define PS_PROTOCOL_VERSION 0x01010007 // Arbitrary protocol
|
||||
#define PS_DEFAULT_PORT 0x5073 // 'P', 's'
|
||||
|
||||
// Defines the list of message types. The order of the list must not change.
|
||||
|
@ -789,26 +789,40 @@ bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event)
|
||||
CNetServerSession* session = (CNetServerSession*)context;
|
||||
CNetServerWorker& server = session->GetServer();
|
||||
|
||||
CAuthenticateMessage* message = (CAuthenticateMessage*)event->GetParamRef();
|
||||
// Prohibit joins while the game is loading
|
||||
if (server.m_State == SERVER_STATE_LOADING)
|
||||
{
|
||||
LOGMESSAGE("Refused connection while the game is loading");
|
||||
session->Disconnect(NDR_SERVER_LOADING);
|
||||
return true;
|
||||
}
|
||||
|
||||
CAuthenticateMessage* message = (CAuthenticateMessage*)event->GetParamRef();
|
||||
CStrW username = server.DeduplicatePlayerName(SanitisePlayerName(message->m_Name));
|
||||
|
||||
bool isRejoining = false;
|
||||
// Optionally allow observers to join after the game has started
|
||||
bool observerLateJoin = false;
|
||||
ScriptInterface& scriptInterface = server.GetScriptInterface();
|
||||
JSContext* cx = scriptInterface.GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
JS::RootedValue settings(cx);
|
||||
scriptInterface.GetProperty(server.m_GameAttributes.get(), "settings", &settings);
|
||||
if (scriptInterface.HasProperty(settings, "ObserverLateJoin"))
|
||||
scriptInterface.GetProperty(settings, "ObserverLateJoin", observerLateJoin);
|
||||
|
||||
// If the game has already started, only allow rejoins
|
||||
bool isRejoining = false;
|
||||
if (server.m_State != SERVER_STATE_PREGAME)
|
||||
{
|
||||
// isRejoining = true; // uncomment this to test rejoining even if the player wasn't connected previously
|
||||
|
||||
// Search for an old disconnected player of the same name
|
||||
// (TODO: if GUIDs were stable, we should use them instead)
|
||||
for (PlayerAssignmentMap::iterator it = server.m_PlayerAssignments.begin(); it != server.m_PlayerAssignments.end(); ++it)
|
||||
{
|
||||
if (!it->second.m_Enabled && it->second.m_Name == username)
|
||||
{
|
||||
isRejoining = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
isRejoining =
|
||||
observerLateJoin ||
|
||||
std::find_if(
|
||||
server.m_PlayerAssignments.begin(), server.m_PlayerAssignments.end(),
|
||||
[&username] (const std::pair<CStr, PlayerAssignment>& pair)
|
||||
{ return pair.second.m_Enabled && pair.second.m_Name == username; })
|
||||
!= server.m_PlayerAssignments.end();
|
||||
|
||||
// Players who weren't already in the game are not allowed to join now that it's started
|
||||
if (!isRejoining)
|
||||
|
Loading…
Reference in New Issue
Block a user