Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework the matchmaker lobby (autolobby) #6479

Merged
merged 85 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
8bf0529
Update annotations
Garanas Oct 15, 2024
914a3d9
Create a standalone and efficient map preview
Garanas Oct 15, 2024
6a535f3
Initial setup with a working preview
Garanas Oct 17, 2024
5fb02fc
First working setup that actually launches into the game
Garanas Oct 17, 2024
beedc76
Separate file for the controller
Garanas Oct 17, 2024
6924eca
Add documentation
Garanas Oct 18, 2024
2c662e0
Remove test function
Garanas Oct 18, 2024
417eb09
Remove old copyright statement
Garanas Oct 18, 2024
320f9f4
Add documentation
Garanas Oct 18, 2024
5473f88
Document behavior of GpgNetSend
Garanas Oct 18, 2024
10a49a2
Add remaining messages to the server
Garanas Oct 18, 2024
6c3c65a
Remove the old autolobby classes module
Garanas Oct 18, 2024
24a7aa4
Add a connection matrix to visualize the status quo
Garanas Oct 19, 2024
ce10a6b
Check support for up to 8 players
Garanas Oct 19, 2024
2abdc11
Use `~=` instead of `not`
Garanas Oct 19, 2024
9607e7e
Remove the wait for hot reload
Garanas Oct 19, 2024
e57b4e8
Make use of `ReusedLayoutFor`
Garanas Oct 19, 2024
a4f4c09
Clean up code
Garanas Oct 19, 2024
7d2d564
Rework messages
Garanas Oct 19, 2024
d1da9f4
Better document the use of the peer identifier
Garanas Oct 19, 2024
5be5fff
Add support for player colors based on the start position.
Garanas Oct 19, 2024
4d00504
Add a comment
Garanas Oct 19, 2024
fbe4183
Introduce a mapping from the peerId to an index
Garanas Oct 19, 2024
d41177b
Add documentation
Garanas Oct 19, 2024
45a5747
Fix prefetch not working properly
Garanas Oct 19, 2024
fb26d78
Introduce a delayed-joining of the lobby
Garanas Oct 19, 2024
1be791b
Improve management of peer indices
Garanas Oct 20, 2024
dd2613e
Add an initial delay before we populate the connection matrix
Garanas Oct 20, 2024
b67ba7e
Fix for peer to index functionality
Garanas Oct 20, 2024
10877ea
Keep track of the lobby creation/hosting/joining parameters
Garanas Oct 20, 2024
2ca02b3
Move GpgNetSend statement to the controller
Garanas Oct 20, 2024
9d86ee4
Create rejoin functionality
Garanas Oct 20, 2024
f5d430a
Always blip the interface when a message is received
Garanas Oct 20, 2024
07ee763
Do not add the interface to the trashbag of the controller
Garanas Oct 20, 2024
6c865fa
Remove reload testing code
Garanas Oct 20, 2024
19a3fa7
Make it crash-happy for 4z0t
Garanas Oct 20, 2024
5e7b21a
expand the matrix
Garanas Oct 20, 2024
e9670d3
Introduce sharing of local launch status
Garanas Oct 22, 2024
a64bba3
Set depth of `reprsl` to 2 by default
Garanas Oct 22, 2024
360fe25
Rename to 'Ready' instead of 'Ready for launch'
Garanas Oct 22, 2024
5823e21
Setup with working reconnect
Garanas Oct 22, 2024
0acd515
Remove LOG statement
Garanas Oct 22, 2024
e3ca5a9
Various tweaks all over
Garanas Oct 22, 2024
4350d0f
Rewrite test logic
Garanas Oct 22, 2024
fa733a9
Fix annotation issues
Garanas Oct 22, 2024
1482163
Reduce time for rejoin to kick in
Garanas Oct 22, 2024
58cf87b
Reduce the update frequency of the status message
Garanas Oct 23, 2024
7259a1f
Improve documentation of server communication
Garanas Oct 25, 2024
4226f96
Improve documentation
Garanas Oct 25, 2024
2e80516
Re-introduce sending player options to the server
Garanas Oct 25, 2024
879f8a1
Extend launch status messages
Garanas Oct 25, 2024
19bff39
Always log the message we send to the server
Garanas Oct 25, 2024
61a3d7d
Simplify the mapping of a peerId to an index for the UI
Garanas Oct 26, 2024
8c4ce67
Remove code that is not used
Garanas Oct 26, 2024
fa9a3d6
Add message validation to perform basic checks of the format of a mes…
Garanas Oct 26, 2024
24fdbd3
Fix functions not being pure
Garanas Oct 26, 2024
f043921
Cleaning up of logic
Garanas Oct 26, 2024
0e1edb5
Undo changes to the launch script
Garanas Oct 26, 2024
5e0547d
Improve annotations
Garanas Oct 26, 2024
d302a3e
Add annotations for scenario save file
Garanas Oct 26, 2024
e42abe8
Add documentation
Garanas Oct 26, 2024
38844a9
Merge branch 'develop' into feature/autolobby
Garanas Oct 27, 2024
53d8a5a
Apply the map utils pull request
Garanas Oct 27, 2024
179ad59
Fix issue with hot reload
Garanas Oct 27, 2024
bfa9d1d
Process feedback of Askaholic
Garanas Oct 27, 2024
c79983e
Send the disconnect message to the server
Garanas Oct 27, 2024
bd8f664
Fix a typo
Garanas Oct 27, 2024
232660e
Improve documentation
Garanas Oct 27, 2024
f621a31
Remove debug code
Garanas Oct 27, 2024
750e51e
Fix typo
Garanas Oct 27, 2024
1922ac6
Show what row/column is of the local client in connection matrix
Garanas Oct 27, 2024
d36e0a7
Add faction-spawn locations to map preview
Garanas Oct 30, 2024
788db99
Fix issue with hot reload
Garanas Oct 31, 2024
577f2e1
Document `SetColorMask`
Garanas Oct 31, 2024
70d37a5
Improve annotations of `StringSplit`
Garanas Oct 31, 2024
bc3be44
Add additional utility functions
Garanas Oct 31, 2024
92ab7f4
Setup for a panel with brackets
Garanas Oct 31, 2024
8df32fb
Revert "Setup for a panel with brackets"
Garanas Nov 19, 2024
523072b
Add brackets
Garanas Nov 19, 2024
e991a71
Disable the rejoin functionality
Garanas Nov 19, 2024
35d23f7
Remove debug code to not launch the game
Garanas Nov 19, 2024
cca7d0b
Removing logging and the like
Garanas Nov 19, 2024
4a1da1e
Merge branch 'develop' into feature/autolobby
Garanas Nov 19, 2024
b62a26a
Remove debugging code
Garanas Nov 19, 2024
10a916d
Add a snippet
Garanas Nov 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions engine/User.lua
Original file line number Diff line number Diff line change
Expand Up @@ -709,14 +709,15 @@ end
---@alias UILobbyProtocols "UDP" | "TCP" | "None

--- For internal use by `CreateLobbyComm()`
---@param lobbyComClass fa-class
---@generic T
---@param lobbyComClass T
---@param protocol UILobbyProtocols
---@param localPort number
---@param maxConnections number
---@param playerName string
---@param playerUID? string
---@param natTraversalProvider? userdata
---@return UILobbyCommunication
---@return T
function InternalCreateLobby(lobbyComClass, protocol, localPort, maxConnections, playerName, playerUID, natTraversalProvider)
end

Expand Down
64 changes: 59 additions & 5 deletions engine/User/CLobby.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
---@meta

---@class moho.lobby_methods : Destroyable


---@class moho.lobby_methods : Destroyable, InternalObject
local CLobby = {}

--- "0", "1", "2", etc.
---@alias UILobbyPlayerId string

---@alias GPGNetAddress string | number

---@class Peer
Expand All @@ -13,8 +18,57 @@ local CLobby = {}
---@field quiet number
---@field status string

--- A piece of data that is one can send with `BroadcastData` or `SendData` to other player(s) in the lobby.
---@class UILobbyReceivedMessage : table
---@field SenderID UILobbyPlayerId # Set by the engine, allows us to identify the source.
---@field SenderName string # Set by the engine, nickname of the source.
---@field Type string # Type of message

--- A piece of data that is one can send with `BroadcastData` or `SendData` to other player(s) in the lobby.
---@class UILobbyData : table
---@field Type string # Type of message

--- All the following fields are read by the engine upon launching the lobby to setup the scenario.
---@class UILobbyLaunchGameOptionsConfiguration
---@field UnitCap any # Read by the engine to determine the initial unit cap. See also the globals `GetArmyUnitCap`, `GetArmyUnitCostTotal` and `SetArmyUnitCap` to manipulate it throughout the scenario.
---@field CheatsEnabled any # Read by the engine to determine whether cheats are enabled.
---@field FogOfWar any # Read by the engine to determine how to manage the fog of war.
---@field NoRushOption any # Read by the engine to create the anti-rush mechanic.
---@field PrebuiltUnits any # Read by the engine to create initial, prebuilt units.
---@field ScenarioFile any # Read by the engine to load the scenario of the game.
---@field Timeouts any # Read by the engine to determine the behavior of time outs.
---@field CivilianAlliance any # Read by the engine to determine the alliance towards civilians.
---@field GameSpeed any # Read by the engine to determine the behavior of game speed (adjustments).

---@class UILobbyLaunchGameModsConfiguration
---@field name string # Read by the engine, TODO
---@field uid string # Read by the engine, TODO

---@class UILobbyLaunchObserverConfiguration
---@field OwnerID UILobbyPlayerId # Read by the engine, TODO
---@field PlayerName string # Read by the engine, TODO

---@class UILobbyLaunchPlayerConfiguration
---@field StartSpot number # Read by Lua code to determine start locations
---@field ArmyName string # Read by the engine, TODO
---@field PlayerName string # Read by the engine, TODO
---@field Civilian boolean # Read by the engine, TODO
---@field Human boolean # Read by the engine, TODO
---@field AIPersonality string # Read by the engine iff Human is false
---@field ArmyColor number # Read by the engine, is mapped to a color by reading the values of `lua\GameColors.lua`.
---@field PlayerColor number # Read by the engine, is mapped to a color by reading the values of `lua\GameColors.lua`
---@field Faction number # Read by the engine to determine the faction of the player.
---@field OwnerID UILobbyPlayerId # Read by the engine, TODO

--- All the following fields are read by the engine upon launching the lobby.
---@class UILobbyLaunchConfiguration
---@field GameMods UILobbyLaunchGameModsConfiguration[] # ModInfo[]
---@field GameOptions UILobbyLaunchGameOptionsConfiguration # GameOptions
---@field Observers UILobbyLaunchObserverConfiguration # PlayerData[]
---@field PlayerOptions UILobbyLaunchPlayerConfiguration[] # PlayerData[]

--- Broadcasts information to all peers. See `SendData` for sending to a specific peer.
---@param data CommunicationData
---@param data UILobbyData
function CLobby:BroadcastData(data)
end

Expand Down Expand Up @@ -45,7 +99,7 @@ function CLobby:EjectPeer(targetID, reason)
end

--- Retrieves the local client identifier.
---@return number
---@return UILobbyPlayerId
function CLobby:GetLocalPlayerID()
end

Expand Down Expand Up @@ -87,7 +141,7 @@ function CLobby:JoinGame(address, remotePlayerName, remotePlayerUID)
end

---
---@param gameConfig GameData
---@param gameConfig UILobbyLaunchConfiguration
function CLobby:LaunchGame(gameConfig)
end

Expand All @@ -106,7 +160,7 @@ end

--- Sends data to a specific peer. See `BroadcastData` for sending to all peers.
---@param targetID string
---@param data CommunicationData
---@param data UILobbyData
function CLobby:SendData(targetID, data)
end

Expand Down
2 changes: 2 additions & 0 deletions engine/User/CUIMapPreview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ end

---
---@param textureName string
---@return boolean
function CUIMapPreview:SetTexture(textureName)
end

---
---@param mapName string
---@return boolean
function CUIMapPreview:SetTextureFromMap(mapName)
end

Expand Down
2 changes: 1 addition & 1 deletion lua/lazyvar.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ local setmetatable = setmetatable

-- Set this true to get tracebacks in error messages. It slows down lazyvars a lot,
-- so don't use except when debugging.
local ExtendedErrorMessages = false
local ExtendedErrorMessages = true
local EvalContext = nil
local WeakKeyMeta = { __mode = 'k' }

Expand Down
108 changes: 108 additions & 0 deletions lua/ui/globals/GpgNetSend.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---@declare-global

--******************************************************************************************************
--** Copyright (c) 2024 Willem 'Jip' Wijnia
--**
--** Permission is hereby granted, free of charge, to any person obtaining a copy
--** of this software and associated documentation files (the "Software"), to deal
--** in the Software without restriction, including without limitation the rights
--** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--** copies of the Software, and to permit persons to whom the Software is
--** furnished to do so, subject to the following conditions:
--**
--** The above copyright notice and this permission notice shall be included in all
--** copies or substantial portions of the Software.
--**
--** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--** SOFTWARE.
--******************************************************************************************************

--- Original function that we should not use directly
local oldGpgNetSend = GpgNetSend

--- Adds a hook that generates sim callbacks for communication to the
--- server. Useful for moderation purposes.
---@param command any
---@param ... unknown
_G.GpgNetSend = function(command, ...)

if SessionIsActive() and not SessionIsReplay() then
local stringifiedArgs = ""
for k = 1, table.getn(arg) do
stringifiedArgs = stringifiedArgs .. tostring(arg[k]) .. ","
end

local currentFocusArmy = GetFocusArmy()
SimCallback(
{
Func = "ModeratorEvent",
Args = {
From = currentFocusArmy,
Message = string.format("GpgNetSend with command '%s' and data '%s'", tostring(command),
stringifiedArgs),
},
}
)
end

oldGpgNetSend(command, unpack(arg))
end

-------------------------------------------------------------------------------
--#region Game <-> Server communications

-- All the following logic is tightly coupled with functionality on either the
-- lobby server, the ice adapter, the java server and/or the client. For more
-- context you can search for the various keywords in the following repositories:
-- - Lobby server: https://github.com/FAForever/server
-- - Java server: https://github.com/FAForever/faf-java-server
-- - Java Ice adapter: https://github.com/FAForever/java-ice-adapter
-- - Kotlin Ice adapter: https://github.com/FAForever/kotlin-ice-adapter
--
-- If we do not send this information then the client is unaware of changes made
-- to the lobby after hosting. These messages are usually only accepted from the
-- host of the lobby.

--- Sends player options to the lobby server. For more context:
--- - https://github.com/search?q=org%3AFAForever+player_option&type=code
---@param peerId UILobbyPlayerId
---@param key 'Team' | 'Army' | 'StartSpot' | 'Faction' | 'Color'
---@param value string | number
GpgNetSendPlayerOption = function(peerId, key, value)
_G.GpgNetSend('PlayerOption', peerId, key, value)
end

--- Sends AI options to the lobby server. For more context:
--- - https://github.com/search?q=org%3AFAForever+ai_option&type=code
---@param key string
---@param value string
GpgNetSendAIOption = function(aiName, key, value)
_G.GpgNetSend('AIOption', aiName, key, value)
end

--- Sends game options to the lobby server. For more context:
--- - https://github.com/search?q=repo%3AFAForever%2Fserver+game_option&type=code
---@param key 'ScenarioFile' | 'Slots' | 'RestrictedCategories'
---@param value string | number
GpgNetSendGameOption = function(key, value)
_G.GpgNetSend('GameOption', key, value)
end

--- Sends game status to the lobby server. For more context:
--- - https://github.com/search?q=repo%3AFAForever%2Fserver+GameState&type=code
---@param value 'None' | 'Idle' | 'Lobby' | 'Launching' | 'Ended'
GpgNetSendGameState = function(value)
_G.GpgNetSend('GameState', value)
end

--- Sends game status to the lobby server. For more context:
--- - https://github.com/search?q=repo%3AFAForever%2Fserver+GameState&type=code
---@param peerId UILobbyPlayerId
GpgNetSendDisconnected = function(peerId)
GpgNetSend('Disconnected', peerId)
end
125 changes: 0 additions & 125 deletions lua/ui/lobby/autolobby-classes.lua

This file was deleted.

Loading