User:Rain/Sandbox: Difference between revisions

From Pavlov VR Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
RCON (Remote Console) is the method with which Pavlov VR servers can be controlled from outside of VR.
'''TODO: Rename the page to "Dedicated server" because THIS IS NOT A GUIDE!'''


== RCON Commands ==
== Hosting ==


=== Placeholders ===
'''There are no Windows binaries'''
Values in [square brackets] are placeholders and must be replaced, or will be replaced by the server in a reply.
=== Server requirements ===
'''OS''': Linux (Ubuntu 18.04 x86_64, Ubuntu 19/04 amd64, Ubuntu 20.04, and Rocky Linux 8 are confirmed working)


[UniqueID] - Player ID (eg. [https://steamid.io/ SteamID64] (PCVR), Oculus Username (Shack))
'''Memory''': 2GB RAM + 1GB RAM per each additional server with 10 players. More RAM is recommended for larger maps, higher player counts, or complex game modes.


[GameMode] - See [[Setting up a dedicated server#Configuring Game.ini|Gamemodes table]] and [[Gamemodes]]
'''CPU''': A ~2.5Ghz CPU will comfortably support a 10 player server. A ~4Ghz CPU will comfortably support 24 players.


[TeamID] - 0 for blue, 1 for red, if there are teams
'''Note''': These are '''not''' hard limits for requirements, just suggestions for the best performance, based on experiences with many server providers on different grades of hardware.


[VehicleID] - See [[Vehicles]]
Pavlov servers are functionally single threaded.


[MapName/ID] - See [[Default Maps|Default maps]] or find the Map ID on Mod.io and append it to "UGC" (Example: https://mod.io/g/pavlov/m/mcdonalds has Resource ID <code>2804322</code>, the MapID to use would be <code>UGC2804322</code>)
=== Software dependencies ===


[SkinID] - See [[ItemIDs#Skins|Skins]]
* gdb (TODO: do you actually need gdb to run a server? wtf?)
* curl (TODO: do you actually need curl to run a server? does pavlov download stuff using curl?)
* lib32gcc1(-s1)
* libc++-dev


[RoleID] - See [[ItemIDs#TTT Roles (Case Sensitive)|TTT Roles]]
=== SteamCMD ===
The app ID for Pavlov VR dedicated servers is <code>622970</code>.


[ItemID] - See [[ItemIDs|Items]]
Instructions on how to use SteamCMD are available in the [https://developer.valvesoftware.com/wiki/SteamCMD Valve Developer Community Wiki].


[True/False] - Either "True" to enable or "False" to disable
To host '''Shack Live''' (Quest) use <code>-beta shack</code>, to host '''Shack RC''' (Quest) use <code>-beta shack_beta</code>.


[Amount] - A number indicating an amount of something
Update 29 of the PCVR version of Pavlov VR dedicated servers require you to completely break your system:
<code>sudo rm /usr/lib/x86_64-linux-gnu/libc++.so</code>
<code>sudo ln -s /usr/lib/x86_64-linux-gnu/libc++.so.1 /usr/lib/x86_64-linux-gnu/libc++.so</code>


=== Reply format ===
'''TODO: By all that is good and fair, modifying system files like this for one piece of software is unacceptable. This can be done in a different, less intrusive way.'''
All command replies are formatted as JSON and inherit this base format:
{
"Command": "[The command name]",
"Comment": "[An optional comment about the command]",
"Successful": "[True/False]"
}
Comment will not exist if the command does not output a comment.


Additional command output is added to the above format. The Example Reply column below only contains this additional command output.
== Configuration ==


Often, commands will contain a field with their own name and a boolean value. This is a very inconsistent value. For example in <code>SetMaxPlayers</code>, if the amount is set to the same as the current slot count, <code>Successful</code> will be <code>true</code> but <code>SetMaxPlayers</code> will be <code>false</code>. However for <code>SwitchTeam</code> for example, if a player is switched to the same team they are already in, <code>SwitchTeam</code> will be <code>true</code> anyway.
=== Moderators, Blacklist, Whitelist ===
The following three files allow you to specify moderators, banned players, and whitelist players.


=== Commands ===
They are required to be able to use <code>AddMod</code>, <code>Ban</code>, <code>Banlist</code>, <code>ModeratorList</code>, <code>RemoveMod</code> and <code>Unban</code> [[Rcon Overview and Commands|RCON commands]] but are otherwise optional.
 
<pre>
Pavlov/Saved/Config/mods.txt
Pavlov/Saved/Config/blacklist.txt
Pavlov/Saved/Config/whitelist.txt
</pre>'''TODO: Describe the file contents, give examples.'''
 
=== Game.ini ===
This file contains the majority of server configuration keys.
It is automatically created when first starting a server, it can also be created manually. <pre>
Pavlov/Saved/Config/LinuxServer/Game.ini
</pre>
 
==== Keys ====
{| class="wikitable"
{| class="wikitable"
|+RCON Commands
|+Game.ini keys
!Command
!Key
!Parameters
!Allowed values
!Default value
!Description
!Description
!Example Command
!Example Reply
|-
|-
|Help
|bEnabled
|none
|<code>True</code><code>False</code>
|Returns the full list of commands and their parameters
|<code>True</code>
|
|Enables or disables registering with the master server to show or hide the server from the server list
Help
'''TODO: confirm that this is true''', and why is this even a thing, you can't direct connect to servers anyways...
|
"Help": [
  "AddMapRotation MapID GameMode",
  ...truncated...
  "UpdateServerName ServerName"
],
|-
|-
|AddMapRotation
|ServerName
|[MapName/ID]
|Any ASCII text value up to 35 characters
[GameMode]
|<code>DedicatedServer</code>
|Adds the specified map with the specified game mode to the bottom of the map rotation.
|Sets the name with which the server will be listed as
Writes the map to <code>Game.ini</code>.
'''TODO: confirm exact maximum character limit and which characters are allowed (utf8? unicode?)'''
|
AddMapRotation sand snd
|
|-
|-
|AddMod
|MaxPlayers
|[UniqueID]
|Integer
|Adds the specified player to the moderator list, making them an admin.
Maximum 10 for Shack, 24 for PC.
Allows them to use the admin menu in the pause menu and be immune to being vote-kicked.
|<code>10</code>
 
|Sets the amount of available player slots
Writes the player to <code>mods.txt</code>.
|
AddMod 12345678901234567
|
"AddMod": true,
"UniqueID": "12345678901234567",
|-
|-
|Ban
|ApiKey
|[UniqueID]
|Obsolete, leave empty.
|Kicks and permanently bans the specified player from the server. They will not be able to join the server anymore.
Writes the player to <code>blacklist.txt</code>.
|
|
Ban 12345678901234567
|
|
"Ban": true,
"UniqueID": "12345678901234567",
|-
|-
|Banlist
|bSecured
|none
|<code>True</code><code>False</code>
|Lists the currently banned player UniqueIDs from <code>blacklist.txt</code>.
|<code>True</code>
|
|Enables or disables Valve Anti-Cheat (VAC)
Banlist
|
"BanList": [
  "12345678901234567",
  "12345678901234568",
  ...truncated...
  "12345678901234569"
],
|-
|-
|Disconnect
|bCustomServer
|none
|<code>True</code><code>False</code>
|Forces the server to closes the RCON connection.
|<code>True</code>
|
|Enables or disables "some new modding tools". Save and HTTP functions.
Disconnect
Required to write to <code>blacklist.txt</code> for bans.
|
'''TODO: specify exactly what those new modding tools are.'''
Goodbye
|-
|-
|EnableCompMode
|bCompetitive
|[True/False]
|<code>True</code><code>False</code>
|Enables or disables competitive mode.
|<code>False</code>
'''Comment''': Comp mode will be changed on map rotation, this updates the config value
|Enables or disables competitive mode for SND
 
Writes to <code>bCompetitive</code> in <code>Game.ini</code>.
|
EnableCompMode true
|
"CompModeState": true,
"EnableCompMode": true,
|-
|-
|EnableVerboseLogging
|bVerboseLogging
|[True/False]
|<code>True</code><code>False</code>
|<code>False</code>
|Enables or disables verbose logging.
|Enables or disables verbose logging.
Writes to <code>bVerboseLogging</code> in <code>Game.ini</code>.
Verbose logging mostly consists of [[Setting up a dedicated server#Verbose Logging|detailed statistics]].
|
This will significantly increase logging.
EnableVerboseLogging false
|
"VerboseLoggingState": false,
"EnableVerboseLogging": true,
|-
|-
|EnableWhitelist
|bWhitelist
|[True/False]
|<code>True</code><code>False</code>
|Enables or disables whitelist usage.
|<code>False</code>
When enabled, only players who are listed in <code>whitelist.txt</code> can join the server.
|Enables or disables usage of the whitelist, allowing only users in <code>whitelist.txt</code> to join
 
Writes to <code>bWhitelist</code> in <code>Game.ini</code>.
|
|
"WhitelistState": true,
"EnableWhitelist": true,
|-
|-
|Gag
|RefreshListTime
|[UniqueID]
|Integer, seconds
[True/False]
|<code>10</code>
|Gags or ungags the specified player.
|Sets the interval at which the server reads changes from <code>mods.txt</code>, <code>blacklist.txt</code> and <code>whitelist.txt</code>
When gagged, players can not use voice chat.
|
|
"Gag": true,
"UniqueID": "12345678901234567",
|-
|-
|GiveAll
|LimitedAmmoType
|[TeamID]
|Integer, Type ID
[ItemID]
|<code>1</code>
|Gives an item to all players on a team.
|Sets the limited ammo type, see [[Setting up a dedicated server#Limited Ammo Types|Limited Ammo Types]]
The <code>GiveItem</code> RCON command description elaborates on how items are placed onto the body of the player.
|
|'''TODO: Couldn't get to execute, always Succesful: false'''
|-
|-
|GiveCash
|TimeLimit
|[UniqueID]
|Integer, minutes
[CashAmount]
|<code>60</code>
|Gives the specified amount of cash to the specified player.
|Sets the time limit for each map
|
GiveCash 12345678901234567 200
|
"GiveCash": true,
"UniqueID": "12345678901234567",
|-
|-
|GiveItem
|TickRate
|[UniqueID]
|Integer, ticks per second
[ItemID]
Recommended between 50 and 120
|Equippes the specified item to the specified player to the corresponding item slot.
|<code>90</code>
Primary guns are placed into the players main hand, replacing the held gun, which will drop.
|Sets the rate at which the server processes and updates game state information and network events.
 
Changes weapon de-spawn time and breaks some game modes. Recommended to leave at default value.
Secondary guns are placed onto the players hip, replacing the holstered gun, which will drop.
'''TODO: what game modes? breaks how? needs clarification.'''
 
Utilities will be placed onto the players chest slots until all slots are full, which will cause given items to be dropped instead.
|
GiveItem 12345678901234567 syringe
|
"GiveItem": true,
"UniqueID": "12345678901234567",
|-
|-
|GiveTeamCash
|Password
|[TeamID]
|Integer, 1 to 4 digit pin
[CashAmount]
|<code>0000</code>
|Adds the specified amount of cash to each member of the specified team.
|Sets the server PIN that is required to be entered before being able to join the server.
|
Setting the pin to <code>0</code> or <code>0000</code> does not remove the pin but sets it to <code>0</code>.
GiveTeamCash 0 200
Commenting out or leaving the value empty will remove the pin.
|
"GiveTeamCash": true,
"TeamID": "0",
|-
|-
|InspectAll
|BalanceTableURL
|none
|Text formatted as <code>user/repository/branch</code>
|Returns a list of InspectPlayer blocks for all players on the server.
|<code>vankruptgames/BalancingTable/main</code>
|
|Sets the balance table Git URL to be used by the server.
InspectAll
See [https://github.com/vankruptgames/BalancingTable Balancing Table] for instructions.
|
"InspectList": [
  {
    "PlayerName": "Username",
    "UniqueId": "12345678901234567",
    "KDA": "3/1/2",
    "Score": "50",
    "Dead": false,
    "Cash": "3450",
    "TeamId": "1",
    "Ping": 39.857143402099609,
    "Gag": false
  },
  ...truncated...
],
|-
|-
|InspectPlayer
|AFKTimeLimit
|[UniqueID]
|Integer, seconds
|Returns a detailed status for the specified player.
|<code>60</code>
The player must be listed in RefreshList.
|Sets the maximum amount of time a player can be idle before being automatically kicked.
|
Setting this to <code>0</code> will disable AFK kicking.
InspectPlayer 12345678901234567
'''TODO: Pretty sure this is incorrect, while testing I've set it to 0 and got kicked nonetheless. Only being moderator prevents afk kicking. Requires further testing.'''
|
"PlayerInfo":
{
 
  "PlayerInfo":
{
  "PlayerName": "Username",
  "UniqueId": "12345678901234567",
  "KDA": "3/1/2",
  "Score": "50",
  "Dead": false,
  "Cash": "3450",
  "TeamId": "1",
  "Ping": 39.857143402099609,
  "Gag": false
},
|-
|-
|InspectTeam
|bInitialized
|[TeamID]
|<code>True</code><code>False</code>
|Returns a list of InspectPlayer blocks for all player on the specified team.
|<code>False</code>
|
|'''TODO: What does this do?'''
InspectTeam 1
|
"InspectList": [
  {
    "PlayerName": "Username",
    "UniqueId": "12345678901234567",
    "KDA": "3/1/2",
    "Score": "50",
    "Dead": false,
    "Cash": "3450",
    "TeamId": "1",
    "Ping": 39.857143402099609,
    "Gag": false
  },
  ...truncated...
],
|-
|-
|ItemList
|DepotURL
|none
|Lists all items in the game and the current map.
Custom items built into the map will be listed.
|
|
ItemList
|
|
"ItemList": [
|'''TODO: What does this do?'''
  "1911",
  "57",
  "acog",
  "adrenaline",
  ...truncated...
  "ww2knife",
  "ww2medkit",
  "ww2painkillers",
  "ww2syringe"
],
|-
|-
|Kick
|bBroadcast
|[UniqueID]
|<code>True</code><code>False</code>
|Kicks the specified player from the server.
|<code>True</code>
|
|Probably enables or disables broadcasting to pavtv?
Kick 12345678901234567
'''TODO: What does this do?'''
|
|}
"UniqueID": "12345678901234567",
'''TODO: Verify all default values, right now I'm just guessing'''
"Kick": true,
 
|-
'''TODO: Sort alphabetically'''
|Kill
 
|[UniqueID]
For maps running a Custom gamemode (CodZ, BR, Duel, etc.) it doesn't matter which gamemode you choose, as the map will automatically override it with the custom mode.
|Kills the specified player.
|
Kill 12345678901234567
|
"UniqueID": "12345678901234567",
"Kill": true,
|-
|MapList
|none
|Returns the current map rotation from Game.ini.
|
MapList
|
"MapList": [
  {
    "MapId": "UGC2863450",
    "GameMode": "SND"
  },
  ...truncated...
  {
    "MapId": "sand",
    "GameMode": "snd"
  }
],
|-
|ModeratorList
|none
|Returns a list of UniqueIDs of all moderators from <code>mods.txt</code>.
|
ModeratorList
|
"ModeratorList": [
  "12345678901234567",
  ...truncated...
  "12345678901234568"
],
|-
|RefreshList
|none
|Returns a list of all connected player names and their corresponding UniqueIDs.
|
RefreshList
|
"PlayerList": [
  {
    "Username": "Username",
    "UniqueId": "12345678901234567"
  },
  ...truncated...
  {
    "Username": "Username2",
    "UniqueId": "12345678901234568"
  }
],
|-
|RemoveMapRotation
|[MapName/ID]
[GameMode]
|Removes the first occurrence of the specified map and game mode combination from the map rotation.
[MapName/ID] and [GameMode]  are case sensitive to the entries in <code>Game.ini</code> or <code>MapList</code> respectively.


Writes the change to <code>Game.ini</code>.
==== Limited Ammo Types ====
|
{| class="wikitable"
RemoveMapRotation sand snd
|+
|
!AmmoType
!Name
!Description
|-
|-
|RemoveMod
|0
|[UniqueID]
|Unlimited
|Removes the specified player from the moderator list.
|Players have unlimited ammo, carry no ammo boxes and do not display an ammo count on the wrist.
Writes the change to <code>mods.txt</code>.
|
RemoveMod 12345678901234567
|
"RemoveMod": true,
"UniqueID": "12345678901234567",
|-
|-
|ResetSND
|1
|none
|Limited Generic
|Reset the currently running SND match.
|Players carry ammo boxes with a limited amount of ammo.
All players will have starting cash, no kills, deaths, assists or score.
One box for each weapon class (Pistol, Submachine gun, Rifles/MGs, Shotgun, Sniper).


All players are killed.
Mags and ammo boxes can be put on the chest of the player to consolidate the ammo.


The score is reset to 0 all.
An ammo count is displayed on the wrist.
|
ResetSND
|
"ResetSND": true,
|-
|-
|PauseMatch
|2
|[Optional Amount]
|Limited Specific
|Pauses the currently running match for the specified amount of seconds.
|Players carry ammo boxes with a limited amount of ammo.
The game is frozen and displays a "Game is paused" countdown timer.
One box for each weapon.


The game is unpaused when amount is not specified or 0.
Mags and ammo boxes can be put on the chest of the player to consolidate the ammo.


Unpausing starts a countdown timer at 15 seconds before unpausing.
An ammo count is displayed on the wrist.
 
Minimum: 0
 
Maximum: 3600
|
PauseMatch 60
|
"PauseTime": 60,
"PauseMatch": true,
|-
|-
|RotateMap
|3
|none
|Custom
|Immediately changes the current map to the next map in the map rotation.
|Allows for full control over ammo by the map.
If the current map was changed to using <code>SwitchMap</code>, the next map will be the one after the previously switched map instead of the immediate map after the current one.
|
RotateMap
|
"RotateMap": true,
|-
|-
|ServerInfo
|4
|none
| Limited Special
|Returns server information such as server name, player count, current map and mode, and more.
|'''All weapons except "special" weapons are unlimited, more clarification is needed.'''
|
ServerInfo
|
"ServerInfo":
{
  "MapLabel": "datacenter",
  "GameMode": "snd",
  "ServerName": "Server name",
  "Teams": true,
  "Team0Score": "4",
  "Team1Score": "1",
  "Round": "6",
  "RoundState": "Started",
  "PlayerCount": "8/10"
},
|-
|-
|SetBalanceTableURL
|5
|[GithubURL]
|Boxless
|Sets the balance table to load from the specified URL.
|'''Like limited generic but without boxes? Clarification is needed.'''
The URL has the format <code>user/repo/branch</code> and must contain a <code>BalancingTable.csv</code>. For example, the [https://github.com/vankruptgames/BalancingTable/blob/Beta_5.1/BalancingTable.csv official balancing table] has the URL <code>vankruptgames/BalancingTable/Beta_5.1</code>. Full URLs (eg. http://...) do not work.
|}


The balance table contains the values for the prices in the buy wheel, how much money is gained from which actions and how much damage is dealt by each weapon including damage falloff and more.
==== Map rotation ====
The map rotation is defined in the <code>Game.ini</code>.


Writes to <code>BalanceTableURL</code> in <code>Game.ini</code>.
Upon server start, the first map in the rotation will be started.
|
SetBalanceTableURL vankruptgames/BalancingTable/Beta_5.1
|
"GithubURL": "<nowiki>https://raw.githubusercontent.com/vankruptgames/BalancingTable/Beta_5.1</nowiki>",
"SetBalanceTableURL": true,
|-
|SetCash
|[UniqueID]
[CashAmount]
|Sets the cash of the specified player to the specified amount.
Minimum: 0


Maximum: 16000
When a map has ended, the next map in the rotation will be started.
|
SetCash 12345678901234567 1000
|
"SetCash": true,
"UniqueID": "12345678901234567",
|-
|SetLimitedAmmoType
|[AmmoType]
|Sets the ammo limitation type.
0 for unlimited, 1 for limited generic, 2 for limited specific, 3 for custom, 4 for limited special, 5 for boxless.


See [[Setting up a dedicated server#Configuring Game.ini|Limited Ammo Types]] for details.
When the end of the rotation has been reached, it will start from the beginning again.


Writes to <code>LimitedAmmoType</code> in <code>Game.ini</code>.
Mod.io maps will be downloaded and updated automatically, if required, when they are rotated to.
|
SetLimitedAmmoType 0
|
"SetLimitedAmmoType": true,
"LimitedAmmoType": "0",
|-
|SetMaxPlayers
|[Amount]
|Sets the amount of slots on the server to the specified amount.
Minimum: 1


Maximum: 24 (PCVR), 10 (Shack)
Each entry requires a separate line of the following format:<pre>
MapRotation=(MapId="Name or ID", GameMode="Game Mode")
</pre><code>Name or ID</code>: See [[Default Maps|Default maps]] or find the Map ID on Mod.io and append it to "UGC" (Example: https://mod.io/g/pavlov/m/mcdonalds has Resource ID <code>2804322</code>, the MapID to use would be <code>UGC2804322</code>)


Writes to <code>MaxPlayers</code> in <code>Game.ini</code>.
<code>Game Mode</code>: See [[Gamemodes|Game Modes]].
|
{| class="wikitable"
SetMaxPlayers 10
|+Game modes
|
!GameMode
"SetMaxPlayers": true,
!Name
"MaxPlayers": 10,
|-
|DM
|Death match
|-
|-
|SetPin
|KOTH
|[Optional PinNumber]
|King of the hill
|Sets the server pin to the specified pin number.
Supplying a pin number locks the server so that player have to enter a pin to join.
 
Not supplying a pin number unlocks the server so that players do not have to enter a pin.
 
PinNumber can be any whole number between 1 and 9999 and may not contain leading zeroes such as <code>0001</code> which would get trimmed to <code>1</code>.
 
Setting the pin to <code>0</code> or <code>0000</code> does not remove the pin but sets it to <code>0</code>.
 
Writes to <code>Password</code> in <code>Game.ini</code>.
|
SetPin 69
|
|-
|-
|SetPlayerSkin
|GUN
|[UniqueID]
| Gun game
[SkinID]
|Sets the player skin of the specified player to the specified skin.
The skin is automatically removed if the player leaves the server, switches teams or upon map change.
 
'''TODO: Test if there are other conditions where the skin is removed.'''
|
SetPlayerSkin 12345678901234567 kevin
|
"SetPlayerSkin": true,
"UniqueID": "12345678901234567",
|-
|-
|SetTimeLimit
|OITC
|[Amount]
| One in the chamber
|Sets the time limit of the current match to the specified amount in seconds.
The match will end once the time limit has counted down to 0.
|
|'''TODO: Couldn't get to execute, always Succesful: false'''
|-
|-
|ShowNametags
|SND
|[True/False]
|Search and destroy
|Enables or disables name tags above friendly players.
|
ShowNametags true
|
"NametagsEnabled": true,
"ShowNametags": true,
|-
|-
|ShutdownServer
|TANKTDM
|none
|WW2 Team Death Match
|Immediately shuts down the server.
|
ShutdownServer
|
|-
|-
|Slap
| TDM
|[UniqueID]
|Team Death Match
[Amount]
|Deals the specified amount of damage to the specified player. Can be lethal if the amount exceeds the current health of the player.
The damage is dealt directly to health and ignores armor.
|
Slap 12345678901234567
|
"UniqueID": "12345678901234567",
|-
|-
|SwitchMap
|TTT
|[MapID]
|Trouble in Terrorist Town
[GameMode]
|Immediately switches to the specified map and game mode.
TDM is automatically selected if no game mode has been specified.
|
SwitchMap datacenter snd
|
"SwitchMap": true,
|-
|-
|SwitchTeam
|WW2GUN
|[UniqueID]
|WW2 gun game
[TeamID]
|Kills and moves the specified player into the specified team.
It will be as if the player has just joined (that team) or if they switched themselves, losing all money, kills, deaths, assists, score and gear.
|
SwitchTeam 12345678901234567 1
|
"SwitchTeam": true,
"UniqueID": "12345678901234567",
|-
|-
|Teleport
|ZWV
|[Source UniqueID]
| Zombie wave survival
[Target UniqueID]
|Teleports the specified source player to the position of the specified target player.
Only works when both the source player and the target player are alive.
|
Teleport 12345678901234567 12345678901234568
|
"MoveUniqueID": "12345678901234567",
"ToUniqueID": "12345678901234568",
"Teleport": true,
|-
|-
|TTTAlwaysEnableSkinMenu
|HIDE
|[True/False]
|The Hidden
|Trouble in Terrorist Town: Enables or disables the skin menu mid-round.
|
|
|-
|-
|TTTEndRound
|INFECTION
|[TeamID]
|Hidden infection
|Trouble in Terrorist Town: Ends the round.
|
|
|-
|-
|TTTFlushKarma
|PUSH
|none
|Push
|Trouble in Terrorist Town: Resets the karma of all players to 1200.
|
|
|-
|-
|TTTGiveCredits
|PH
|[UniqueID]
|Prop hunt
[Amount]
|}
|Trouble in Terrorist Town: Adds the specified amount of TTT credits to the specified player.
'''TODO: move this to game modes page.'''
|
 
|
==== Example ====
<pre>
[/Script/Pavlov.DedicatedServer]
# This is a comment
bEnabled=True
ServerName=Your server
MaxPlayers=10
bSecured=True
bCustomServer=True
bWhitelist=False
RefreshListTime=120
LimitedAmmoType=0
TickRate=90
TimeLimit=60
Password=1234
bInitialized=False
DepotURL=
ApiKey=
bCompetitive=False
bBroadcast=True
BalanceTableURL=vankruptgames/BalancingTable/Beta_5.1
bVerboseLogging=True
AFKTimeLimit=0
 
MapRotation=(MapId="datacenter", GameMode="SND")
MapRotation=(MapId="UGC3094680", GameMode="SND")
MapRotation=(MapId="UGC2996823", GameMode="SND")
MapRotation=(MapId="sand", GameMode="SND")
MapRotation=(MapId="UGC2841131", GameMode="SND")
MapRotation=(MapId="UGC2829349", GameMode="SND")
MapRotation=(MapId="container", GameMode="SND")
MapRotation=(MapId="UGC2844898", GameMode="SND")
MapRotation=(MapId="UGC2804502", GameMode="SND")
</pre>
 
=== RCON ===
The RCON password and port are configured in <code>RconSettings.txt</code>. If the file does not exist or if the values in it are empty, no RCON will be provided.<pre>
Pavlov/Saved/Config/RconSettings.txt
</pre>
 
==== Keys ====
{| class="wikitable"
!Key
!Allowed values
!Default value
!Description
|-
|-
|TTTPauseTimer
|Password
|[True/False]
|Text
|Trouble in Terrorist Town: Pauses the timer.
|<code>changeme</code>
|
|Sets the password used to authenticate with RCON
|
|-
|-
|TTTSetKarma
|Port
|[UniqueID]
|Integer, 0-65535
[Amount]
|<code>9100</code>
|Trouble in Terrorist Town: Sets the karma of the specified player to the specified amount.
|Sets the port at which RCON will listen
|
|}
|
 
==== Example ====
<pre>
Password=very secure password
Port=9100
</pre>
 
== Running ==
 
==== Startup parameters ====
{| class="wikitable"
|+
!Parameter
!Description
|-
|-
|TTTSetRole
|[UniqueID]
[RoleID]
|Trouble in Terrorist Town: Sets the TTT role of the specified player to the specified role.
|
|
|
-PORT=7777
|Sets the server port to listen to.
Secondary port is <code>port + 400</code>.
For example: Base port <code>7777</code>, secondary port <code>8177</code>.
|-
|-
|Unban
|[UniqueID]
|Unbans the specified player so that they can join again.
Writes the change to <code>blacklist.txt</code>.
|
|
  Unban 12345678901234567
  -COMPETITIVE=1
|
|Enables competitive mode.
"Unban": true,
This is the same as enabling competitive move in the <code>Game.ini</code>.
"UniqueID": "12345678901234567",
|-
|-
|UpdateServerName
|[Name]
|Changes the server name to the specified name.
Writes to <code>ServerName</code> in <code>Game.ini</code>.
|
|
UpdateServerName My server name
|'''TODO: Ask dev for complete list of arguments or, much easier and faster, decompile the binary and find them.'''
|
"ServerName": "My server name",
"UpdateServerName": true,
|}
|}


----
==== Server executable ====
With the server files, a startup script <code>PavlovServer.sh</code> is shipped. It adds global execution privileges to the server executable, and adds an argument <code>Pavlov</code> to the startup parameters.
 
The server executable is located in <code>Pavlov/Binaries/Linux/PavlovServer-Linux-Shipping</code> and can be executed directly. It already has global execution privileges by default.
 
Either of these can be used to start the server, the <code>PavlovServer.sh</code> script will forward all startup parameters to the server executable.
 
== Shack ==
Shack servers and PCVR servers have a few differences which will be described in this section.
 
'''TODO: Since there are also 2 shack versions, documenting all this is a huge chore, especially for someone who doesn't touch this sh..izzle.'''
 
=== Game.ini keys ===
The following keys do not exist for Shack servers.


== Connecting to RCON ==
* '''TODO'''
RCON uses a simple UTF-8 TCP text stream allowing for a multitude of ways to connect.


=== Authentication ===
=== Custom maps ===
After connecting to RCON, the first message sent is by the server requesting the RCON password to be transmitted.
Shack (both versions??) do not support Mod.io and require manual upload of any custom map.


For this, the server sends a 10 byte message "<code>Password:</code> " (including the trailing space) to the client.
Also players download the custom maps directly from the server?


The client is expected to reply with the password as lowercase hex representation of the MD5 checksum of the password.
'''TODO: Needs figuring out!'''


No line feed or carriage return character must be transmitted as part of the password.
To use custom maps, the maps folder first needs to be created manually.
Pavlov/Saved/maps
Custom map folders will need to be placed into this folder.


If the password is correct, the server will reply with <code>Authenticated=1\r\n</code> or if the password was incorrect, the reply will be <code>Authenticated=0\r\n</code>.
For example:<pre>Pavlov/Saved/maps
|- SVR_Arena
|- metadata.json
|- other mod files
|- SRV_Industrial
|- metadata.json
|- ...</pre>


'''Example'''
==== Downloading Shack maps ====
There are multiple places where you can download shack maps. Some maps are provided by the map creator.


Authentication using the password "hello test".
* https://www.pavlovquest.com/maps
> Password:  
* https://pavlovhorde.com/mapsList
< 7a6d667ea5ed4467c017b2ed6ea07e78
* #shack-map-showcase in the Pavlov VR Discord ('''TODO: link it!''')
> Authenticated=1\r\n


=== Sending commands and receiving replies ===
=== Server executable ===
Any data sent to the server and terminated by a line feed character will be interpreted as a command and executed.
PavlovServer.sh exists for shack? does it do the same useless additional stuff?


This is followed by the server sending the corresponding command response in JSON format with new lines being indicated by a line feed character
Is the name of the executable the same? For both shack versions?


The response is terminated with a carriage return and line feed.
'''TODO: Needs figuring out!'''


'''Example'''
----
----
----
----
----
----
----
----
----
----
----
----


Executing the command <code>ServerInfo</code>.
==== Shack Maps (Quest) ====
< ServerInfo\n
> {\n\t"Command": "ServerInfo",\n\t"ServerInfo":\n\t{\n\t\t"MapLabel": "UGC2863450",\n\t\t"GameMode": "SND",\n\t\t"ServerName": "Server name",\n\t\t"Teams": true,\n\t\t"Team0Score": "0",\n\t\t"Team1Score": "3",\n\t\t"Round": "3",\n\t\t"RoundState": "Ended",\n\t\t"PlayerCount": "0/10"\n\t},\n\t"Successful": true\n}\r\n


== Tools for connecting to RCON ==
If you try to use the steps above to add maps for Shack, youll run into issues very quickly. This is because Shack has no affiliation to Steam, and therefore cannot use Steam Workshop maps like above. In the future, these steps will apply to PC servers as well, allowing a server to hold the map itself, instead of offloading to Steam.


=== Third party hosted tools ===
To get started, first create the directory to hold the maps
The easiest way to access RCON is to use a third party hosted tool. These are websites that take the RCON connection information and provide an RCON web interface.


'''Warning''': These tools may not be open source and can steal RCON passwords! Because they are hosted by third parties, it is impossible to verify that they do not.
<pre>mkdir -p /home/steam/pavlovserver/Pavlov/Saved/maps</pre>


* [https://pavlovrcon.com/ PavlovRCON.com]: A web-based RCON client
You can use any number of methods to move the map files onto the server, but ill go over the two simplest, starting with a GUI approach
* [https://discord.com/oauth2/authorize?client_id=780880728992383077&scope=bot&permissions=199744 Horde Bot]: Discord bot specific to [[Hosting Providers|Horde servers]]


=== Third party local tools ===
Download and install CyberDuck onto your "home" PC (Whatever PC you use for access to the server, but not the server itsself): https://cyberduck.io/
These are programs that are downloaded and ran locally to provide an RCON interface.


'''Warning''': If a tool is not open source it is not easily possible to verify that it does not steal RCON passwords. It is recommended to only use open source tools that can be verified.
Next, download and unzip your map of choice from https://www.pavlovquest.com/ , https://pavlovhorde.com/mapsList, or look in #shack-map-showcase channel in the discord server.  I'm going to use Cheeto's WW2 Items test (http://www.mediafire.com/file/emyt9bs1z9u9ykw/SVR_Cheeto_Items.zip/file ) for this example, you do what you like


* [https://github.com/Oakraven79/pavlov_rcon_tcl pavlov_rcon_tcl]: Python based UI which is designed to be usable from within VR. Standalone executable. Requires editing of configuration files.
In the top left corner, open a connection, set the connection type to SFTP, and fill in the rest of the information. User will be root, password is whatever you set the root pw as (toor in Ubuntu by default)
* [https://github.com/Krzychu81/pavlov-vr-rcon pavlov-vr-rcon]: node.js based web UI which is designed to be usable from within VR. Requires node.js.


=== Third party self hosted tools ===
In the directory dropdown (itll say /root) go back to /
These are services that need to be self hosted.


'''Warning''': If a tool is not open source it is not easily possible to verify that it does not steal RCON passwords. It is recommended to only use open source tools that can be verified.
Follow the directories until we arrive back at our "maps" folder <pre>/home/steam/pavlovserver/Pavlov/Saved/maps</pre>


* [https://github.com/devinSpitz/PavlovRconWebserver PavlovRconWebserver]: Feature-rich all-in-one hosting solution.
Drag and drop the unzipped map folder into the main window, in this case itll be SVR_Cheeto_Items
* [https://github.com/Longoon12000/PterodactylPavlovServerController PPSC]: [https://pterodactyl.io/ Pterodactyl]-based feature-rich server management software. Requires the servers to run through Pterodactyl.
* [https://github.com/makupi/pavlov-bot pavlov-bot]: A bot that allows for using RCON through Discord.


=== Direct connect ===
Hit Allow
Since the RCON protocol is plain text TCP, direct connection terminals can be used to connect to RCON.


==== Netcat ====
Youll now see a folder named SVR_Cheeto_Items, and within it should be nothing but 3 files. If there is another folder in it, move this folder to the maps directory, otherwise the server wont work. The 3 files (2 .PAK one .JSON) should be in home/steam/pavlovserver/Pavlov/Saved/maps/SVR_Cheeto_Items, no more, no less.
nc ip-or-domain.com port
'''Example'''
❯ nc myserver.com 9101
Password: 7a6d667ea5ed4467c017b2ed6ea07e78
Authenticated=1
ServerInfo
{
        "Command": "ServerInfo",
        "ServerInfo":
        {
                "MapLabel": "sand",
                "GameMode": "snd",
                "ServerName": "My server",
                "Teams": true,
                "Team0Score": "0",
                "Team1Score": "2",
                "Round": "2",
                "RoundState": "Started",
                "PlayerCount": "0/10"
        },
        "Successful": true
}
Disconnect
Goodbye


==== Telnet ====
Pavlov Shack servers load maps at pavlovserver start.  '''YOU MUST RESTART THE GAME SERVER TO USE THE MAPS.'''
'''TODO: Telnet does not seem to work. Confirmation required.'''


=== Libraries ===
To play the map, you can either use RCON switch map command, or to add the map to your servers automatic map rotation list, add the map's folder name to your Game.ini. This replaces the MapID section, so for our example it would be
These are libraries for developers to interface with RCON.


* [https://github.com/Longoon12000/PavlovVR-Rcon PavlovVR-Rcon]: .net 7 library written in C#
<pre>MapRotation=(MapId="SVR_Cheeto_Items", GameMode="TDM")</pre>
* [https://github.com/kaylynn234/rcon rcon]: Python library
* [https://github.com/makupi/async-pavlov async-pavlov]: Asynchronous python library


==== Tips on developing apps to use RCON ====
And thats all! Disconnect CyberDuck from your server before playing, otherwise youll have difficulty joining.
It should be avoided to open a new connection for each command. It may cause performance issues.


It should be avoided to send multiple commands directly one after the other without a delay of 100ms. It may cause commands to be dropped.


Commands are not executed during a map change.
[[Category:RCON automation]]

Latest revision as of 03:46, 6 July 2023

TODO: Rename the page to "Dedicated server" because THIS IS NOT A GUIDE!

Hosting

There are no Windows binaries

Server requirements

OS: Linux (Ubuntu 18.04 x86_64, Ubuntu 19/04 amd64, Ubuntu 20.04, and Rocky Linux 8 are confirmed working)

Memory: 2GB RAM + 1GB RAM per each additional server with 10 players. More RAM is recommended for larger maps, higher player counts, or complex game modes.

CPU: A ~2.5Ghz CPU will comfortably support a 10 player server. A ~4Ghz CPU will comfortably support 24 players.

Note: These are not hard limits for requirements, just suggestions for the best performance, based on experiences with many server providers on different grades of hardware.

Pavlov servers are functionally single threaded.

Software dependencies

  • gdb (TODO: do you actually need gdb to run a server? wtf?)
  • curl (TODO: do you actually need curl to run a server? does pavlov download stuff using curl?)
  • lib32gcc1(-s1)
  • libc++-dev

SteamCMD

The app ID for Pavlov VR dedicated servers is 622970.

Instructions on how to use SteamCMD are available in the Valve Developer Community Wiki.

To host Shack Live (Quest) use -beta shack, to host Shack RC (Quest) use -beta shack_beta.

Update 29 of the PCVR version of Pavlov VR dedicated servers require you to completely break your system:

sudo rm /usr/lib/x86_64-linux-gnu/libc++.so 
sudo ln -s /usr/lib/x86_64-linux-gnu/libc++.so.1 /usr/lib/x86_64-linux-gnu/libc++.so

TODO: By all that is good and fair, modifying system files like this for one piece of software is unacceptable. This can be done in a different, less intrusive way.

Configuration

Moderators, Blacklist, Whitelist

The following three files allow you to specify moderators, banned players, and whitelist players.

They are required to be able to use AddMod, Ban, Banlist, ModeratorList, RemoveMod and Unban RCON commands but are otherwise optional.

Pavlov/Saved/Config/mods.txt
Pavlov/Saved/Config/blacklist.txt
Pavlov/Saved/Config/whitelist.txt

TODO: Describe the file contents, give examples.

Game.ini

This file contains the majority of server configuration keys.

It is automatically created when first starting a server, it can also be created manually.

Pavlov/Saved/Config/LinuxServer/Game.ini

Keys

Game.ini keys
Key Allowed values Default value Description
bEnabled TrueFalse True Enables or disables registering with the master server to show or hide the server from the server list

TODO: confirm that this is true, and why is this even a thing, you can't direct connect to servers anyways...

ServerName Any ASCII text value up to 35 characters DedicatedServer Sets the name with which the server will be listed as

TODO: confirm exact maximum character limit and which characters are allowed (utf8? unicode?)

MaxPlayers Integer

Maximum 10 for Shack, 24 for PC.

10 Sets the amount of available player slots
ApiKey Obsolete, leave empty.
bSecured TrueFalse True Enables or disables Valve Anti-Cheat (VAC)
bCustomServer TrueFalse True Enables or disables "some new modding tools". Save and HTTP functions.

Required to write to blacklist.txt for bans. TODO: specify exactly what those new modding tools are.

bCompetitive TrueFalse False Enables or disables competitive mode for SND
bVerboseLogging TrueFalse False Enables or disables verbose logging.

Verbose logging mostly consists of detailed statistics. This will significantly increase logging.

bWhitelist TrueFalse False Enables or disables usage of the whitelist, allowing only users in whitelist.txt to join
RefreshListTime Integer, seconds 10 Sets the interval at which the server reads changes from mods.txt, blacklist.txt and whitelist.txt
LimitedAmmoType Integer, Type ID 1 Sets the limited ammo type, see Limited Ammo Types
TimeLimit Integer, minutes 60 Sets the time limit for each map
TickRate Integer, ticks per second

Recommended between 50 and 120

90 Sets the rate at which the server processes and updates game state information and network events.

Changes weapon de-spawn time and breaks some game modes. Recommended to leave at default value. TODO: what game modes? breaks how? needs clarification.

Password Integer, 1 to 4 digit pin 0000 Sets the server PIN that is required to be entered before being able to join the server.

Setting the pin to 0 or 0000 does not remove the pin but sets it to 0. Commenting out or leaving the value empty will remove the pin.

BalanceTableURL Text formatted as user/repository/branch vankruptgames/BalancingTable/main Sets the balance table Git URL to be used by the server.

See Balancing Table for instructions.

AFKTimeLimit Integer, seconds 60 Sets the maximum amount of time a player can be idle before being automatically kicked.

Setting this to 0 will disable AFK kicking. TODO: Pretty sure this is incorrect, while testing I've set it to 0 and got kicked nonetheless. Only being moderator prevents afk kicking. Requires further testing.

bInitialized TrueFalse False TODO: What does this do?
DepotURL TODO: What does this do?
bBroadcast TrueFalse True Probably enables or disables broadcasting to pavtv?

TODO: What does this do?

TODO: Verify all default values, right now I'm just guessing

TODO: Sort alphabetically

For maps running a Custom gamemode (CodZ, BR, Duel, etc.) it doesn't matter which gamemode you choose, as the map will automatically override it with the custom mode.

Limited Ammo Types

AmmoType Name Description
0 Unlimited Players have unlimited ammo, carry no ammo boxes and do not display an ammo count on the wrist.
1 Limited Generic Players carry ammo boxes with a limited amount of ammo.

One box for each weapon class (Pistol, Submachine gun, Rifles/MGs, Shotgun, Sniper).

Mags and ammo boxes can be put on the chest of the player to consolidate the ammo.

An ammo count is displayed on the wrist.

2 Limited Specific Players carry ammo boxes with a limited amount of ammo.

One box for each weapon.

Mags and ammo boxes can be put on the chest of the player to consolidate the ammo.

An ammo count is displayed on the wrist.

3 Custom Allows for full control over ammo by the map.
4 Limited Special All weapons except "special" weapons are unlimited, more clarification is needed.
5 Boxless Like limited generic but without boxes? Clarification is needed.

Map rotation

The map rotation is defined in the Game.ini.

Upon server start, the first map in the rotation will be started.

When a map has ended, the next map in the rotation will be started.

When the end of the rotation has been reached, it will start from the beginning again.

Mod.io maps will be downloaded and updated automatically, if required, when they are rotated to.

Each entry requires a separate line of the following format:

MapRotation=(MapId="Name or ID", GameMode="Game Mode")

Name or ID: See Default maps or find the Map ID on Mod.io and append it to "UGC" (Example: https://mod.io/g/pavlov/m/mcdonalds has Resource ID 2804322, the MapID to use would be UGC2804322)

Game Mode: See Game Modes.

Game modes
GameMode Name
DM Death match
KOTH King of the hill
GUN Gun game
OITC One in the chamber
SND Search and destroy
TANKTDM WW2 Team Death Match
TDM Team Death Match
TTT Trouble in Terrorist Town
WW2GUN WW2 gun game
ZWV Zombie wave survival
HIDE The Hidden
INFECTION Hidden infection
PUSH Push
PH Prop hunt

TODO: move this to game modes page.

Example

[/Script/Pavlov.DedicatedServer]
# This is a comment
bEnabled=True
ServerName=Your server
MaxPlayers=10
bSecured=True
bCustomServer=True
bWhitelist=False
RefreshListTime=120
LimitedAmmoType=0
TickRate=90
TimeLimit=60
Password=1234
bInitialized=False
DepotURL=
ApiKey=
bCompetitive=False
bBroadcast=True
BalanceTableURL=vankruptgames/BalancingTable/Beta_5.1
bVerboseLogging=True
AFKTimeLimit=0

MapRotation=(MapId="datacenter", GameMode="SND")
MapRotation=(MapId="UGC3094680", GameMode="SND")
MapRotation=(MapId="UGC2996823", GameMode="SND")
MapRotation=(MapId="sand", GameMode="SND")
MapRotation=(MapId="UGC2841131", GameMode="SND")
MapRotation=(MapId="UGC2829349", GameMode="SND")
MapRotation=(MapId="container", GameMode="SND")
MapRotation=(MapId="UGC2844898", GameMode="SND")
MapRotation=(MapId="UGC2804502", GameMode="SND")

RCON

The RCON password and port are configured in RconSettings.txt. If the file does not exist or if the values in it are empty, no RCON will be provided.

Pavlov/Saved/Config/RconSettings.txt

Keys

Key Allowed values Default value Description
Password Text changeme Sets the password used to authenticate with RCON
Port Integer, 0-65535 9100 Sets the port at which RCON will listen

Example

Password=very secure password
Port=9100

Running

Startup parameters

Parameter Description
-PORT=7777
Sets the server port to listen to.

Secondary port is port + 400. For example: Base port 7777, secondary port 8177.

-COMPETITIVE=1
Enables competitive mode.

This is the same as enabling competitive move in the Game.ini.

TODO: Ask dev for complete list of arguments or, much easier and faster, decompile the binary and find them.

Server executable

With the server files, a startup script PavlovServer.sh is shipped. It adds global execution privileges to the server executable, and adds an argument Pavlov to the startup parameters.

The server executable is located in Pavlov/Binaries/Linux/PavlovServer-Linux-Shipping and can be executed directly. It already has global execution privileges by default.

Either of these can be used to start the server, the PavlovServer.sh script will forward all startup parameters to the server executable.

Shack

Shack servers and PCVR servers have a few differences which will be described in this section.

TODO: Since there are also 2 shack versions, documenting all this is a huge chore, especially for someone who doesn't touch this sh..izzle.

Game.ini keys

The following keys do not exist for Shack servers.

  • TODO

Custom maps

Shack (both versions??) do not support Mod.io and require manual upload of any custom map.

Also players download the custom maps directly from the server?

TODO: Needs figuring out!

To use custom maps, the maps folder first needs to be created manually.

Pavlov/Saved/maps

Custom map folders will need to be placed into this folder.

For example:

Pavlov/Saved/maps
|- SVR_Arena
 |- metadata.json
 |- other mod files
|- SRV_Industrial
 |- metadata.json
 |- ...

Downloading Shack maps

There are multiple places where you can download shack maps. Some maps are provided by the map creator.

Server executable

PavlovServer.sh exists for shack? does it do the same useless additional stuff?

Is the name of the executable the same? For both shack versions?

TODO: Needs figuring out!













Shack Maps (Quest)

If you try to use the steps above to add maps for Shack, youll run into issues very quickly. This is because Shack has no affiliation to Steam, and therefore cannot use Steam Workshop maps like above. In the future, these steps will apply to PC servers as well, allowing a server to hold the map itself, instead of offloading to Steam.

To get started, first create the directory to hold the maps

mkdir -p /home/steam/pavlovserver/Pavlov/Saved/maps

You can use any number of methods to move the map files onto the server, but ill go over the two simplest, starting with a GUI approach

Download and install CyberDuck onto your "home" PC (Whatever PC you use for access to the server, but not the server itsself): https://cyberduck.io/

Next, download and unzip your map of choice from https://www.pavlovquest.com/ , https://pavlovhorde.com/mapsList, or look in #shack-map-showcase channel in the discord server. I'm going to use Cheeto's WW2 Items test (http://www.mediafire.com/file/emyt9bs1z9u9ykw/SVR_Cheeto_Items.zip/file ) for this example, you do what you like

In the top left corner, open a connection, set the connection type to SFTP, and fill in the rest of the information. User will be root, password is whatever you set the root pw as (toor in Ubuntu by default)

In the directory dropdown (itll say /root) go back to /

Follow the directories until we arrive back at our "maps" folder

/home/steam/pavlovserver/Pavlov/Saved/maps

Drag and drop the unzipped map folder into the main window, in this case itll be SVR_Cheeto_Items

Hit Allow

Youll now see a folder named SVR_Cheeto_Items, and within it should be nothing but 3 files. If there is another folder in it, move this folder to the maps directory, otherwise the server wont work. The 3 files (2 .PAK one .JSON) should be in home/steam/pavlovserver/Pavlov/Saved/maps/SVR_Cheeto_Items, no more, no less.

Pavlov Shack servers load maps at pavlovserver start. YOU MUST RESTART THE GAME SERVER TO USE THE MAPS.

To play the map, you can either use RCON switch map command, or to add the map to your servers automatic map rotation list, add the map's folder name to your Game.ini. This replaces the MapID section, so for our example it would be

MapRotation=(MapId="SVR_Cheeto_Items", GameMode="TDM")

And thats all! Disconnect CyberDuck from your server before playing, otherwise youll have difficulty joining.