Update content, update to latest Hugo
This commit is contained in:
parent
f89b28be60
commit
0c99aa7482
29 changed files with 302 additions and 104 deletions
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
- name: Setup Hugo
|
||||
uses: peaceiris/actions-hugo@v3
|
||||
with:
|
||||
hugo-version: '0.126.1'
|
||||
hugo-version: '0.145.0'
|
||||
extended: true
|
||||
|
||||
- name: Build
|
||||
|
|
|
@ -17,4 +17,6 @@ markup:
|
|||
title: 'XIV Docs'
|
||||
theme: 'mytheme'
|
||||
timeZone: 'UTC'
|
||||
|
||||
pagination:
|
||||
paginate: 20
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
title: "Home"
|
||||
---
|
||||
|
||||
A garden of knowledge on FFXIV, a certain critically acclaimed MMO. Most of this is centered around A Realm Reborn (2.x+)
|
||||
My garden of knowledge of a certain, critically acclaimed MMO. Most of this information is about A Realm Reborn (2.x+) and later expansions.
|
||||
|
||||
# See Also
|
||||
|
||||
|
|
5
content/concept/account-id.md
Normal file
5
content/concept/account-id.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "Account ID"
|
||||
---
|
||||
|
||||
This is a unique number assigned to a service account.
|
5
content/concept/content-id.md
Normal file
5
content/concept/content-id.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "Content ID"
|
||||
---
|
||||
|
||||
This is a unique number assigned to each player character.
|
|
@ -1,26 +0,0 @@
|
|||
---
|
||||
title: "Building Dalamud plugins on Linux"
|
||||
---
|
||||
|
||||
Believe it or not, it's actually very easy to develop with Dalamud on Linux since they moved to .NET Core!
|
||||
|
||||
For example, in [JetBrain's Rider](https://www.jetbrains.com/rider/) you can open any Dalamud project and have it build out of the box.
|
||||
|
||||
# The .NET SDK
|
||||
|
||||
You need the .NET SDK of course, which is in many package managers:
|
||||
|
||||
* Fedora Linux: `dotnet`
|
||||
* Arch Linux: `dotnet-sdk`
|
||||
* Gentoo Linux: `dotnet-sdk` or `dotnet-sdk-bin`
|
||||
|
||||
# Fixing DalamudLibPath
|
||||
|
||||
Depending on the plugin, it might already have sensible paths to the Dalamud library folder. The [SamplePlugin](https://github.com/goatcorp/SamplePlugin/blob/master/SamplePlugin/SamplePlugin.csproj#L33) is an example of this. If it doesn't, or you don't use XIVQuickLauncher/XIV.Core then you need to manually edit the path. Tweak the `<DalamudLibPath>` folder to the location where your `Dalamud.dll` and files sit, and you'll know when you're successful when .NET stops screaming.
|
||||
|
||||
If for some reason your build of Dalamud is not a developer-enabled one, check the [Dalamud release server](https://kamori.goats.dev/Dalamud/Release/VersionInfo?track=) for a download URL.
|
||||
|
||||
# The devPlugin path
|
||||
|
||||
Remember that when entering the dev plugin path in the Dalamud settings, to prepend it with `Z:` and take care of your slashes so they make sense under Wine.
|
||||
|
145
content/concept/event-scripts.md
Normal file
145
content/concept/event-scripts.md
Normal file
|
@ -0,0 +1,145 @@
|
|||
---
|
||||
title: "Client-Side Scripts"
|
||||
---
|
||||
|
||||
Events are scripted using [Lua](https://lua.org/), and are shipped with the client as bytecode. One example is `game_script/quest/047/FesSxt103_04798.luab`, notice the `.luab` extension.
|
||||
|
||||
The version of Lua used in the client is Lua 5.1. They don't seem to modify much - if any - of the base Lua state - including [dangerous stuff like the os module](https://notnite.com/blog/ffxiv-modloader-ace) that's not needed for client-side scripts.
|
||||
|
||||
# Decompiling
|
||||
|
||||
Decompiling the bytecode is trivial, one tool that can be used is [unluac](https://sourceforge.net/projects/unluac/). But there many other 5.1 decompilers available online.
|
||||
|
||||
Since only the bytecode remains, there's very little useful information left in the file. Much of the logic and API calls are intact though!
|
||||
|
||||
# API
|
||||
|
||||
Here are the currently known functions of the API:
|
||||
|
||||
---
|
||||
|
||||
## Class `Pc`
|
||||
|
||||
**`IsWarriorOfLight()` → `boolean`**
|
||||
|
||||
Unknown purpose. But probably returns true if the player character is legacy (1.x).
|
||||
|
||||
**`IsHowTo{id=…}` → `boolean`**
|
||||
|
||||
Unknown purpose.
|
||||
|
||||
---
|
||||
|
||||
## Class `EventHandler`
|
||||
|
||||
See `game_script/system/EventHandler.luab` for various constants used throughout event scripts.
|
||||
|
||||
**`PlayBGM{id=…}`**
|
||||
|
||||
Unknown purpose. But probably plays BGM.
|
||||
|
||||
**`FadeOut{unk=…}`**
|
||||
|
||||
Unknown purpose. But probably fades out the screen.
|
||||
|
||||
**`WaitForFade()`**
|
||||
|
||||
Unknown purpose. But probably waits for the current fade to stop animating.
|
||||
|
||||
**`BeginCutScene()`**
|
||||
|
||||
Unknown purpose. But probably starts preparing a cutscene to play.
|
||||
|
||||
**`PlayCutScene{unk=…}`**
|
||||
|
||||
Unknown purpose. But probably plays a cutscene.
|
||||
|
||||
**`EndCutScene()`**
|
||||
|
||||
Unknown purpose. But probably ends the current cutscene.
|
||||
|
||||
**`DisableSceneSkip()`**
|
||||
|
||||
Unknown prupose. But probably prevents the player from skipping the cutscene.
|
||||
|
||||
**`FadeIn{unk=…}`**
|
||||
|
||||
Unknown purpose. But probably starts a fade in animation.
|
||||
|
||||
**`EnableSceneSkip()`**
|
||||
|
||||
Unknown purpose. But probably allows the player to skip the cutscene.
|
||||
|
||||
**`LoadMovePosition{unk=…}`**
|
||||
|
||||
Unknown purpose.
|
||||
|
||||
**`HowTo{id=…}`**
|
||||
|
||||
Unknown purpose.
|
||||
|
||||
**`GetTerritoryType()` → `unk`**
|
||||
|
||||
Unknown purpose. But probably returns the current territory type id.
|
||||
|
||||
**`PlayLandscapeCamera{unk=…}`**
|
||||
|
||||
Unknown purpose. But probably moves the current camera to a set landscape camera.
|
||||
|
||||
**`Zoom{unk=…, unk=…, unk=…, unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose. But probably begins zooming the camera.
|
||||
|
||||
**`Wait{unk=…}`**
|
||||
|
||||
Unknown purpose. But probably waits for a set amount of time.
|
||||
|
||||
**`UpdownPan{unk=…, unk=…, unk=…, unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose. But probably pan related.
|
||||
|
||||
**`SidePan{unk=…, unk=…, unk=…, unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose. But probably pan related.
|
||||
|
||||
**`PlayScreenShake{unk=…, unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose. But probably starts shaking the screen.
|
||||
|
||||
**`StopScreenShake{unk=…}`**
|
||||
|
||||
Unknown purpose. But probably stops shaking the screen.
|
||||
|
||||
**`ScreenImage{unk=…}`**
|
||||
|
||||
Unknown purpose. But probably shows a set image on the screen.
|
||||
|
||||
---
|
||||
|
||||
## Class `Opening`
|
||||
|
||||
**`EnableEventRange{unk=…, unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose.
|
||||
|
||||
**`DisableEventRange{unk=…, unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose.
|
||||
|
||||
---
|
||||
|
||||
## Class `Chara` extends `Actor`
|
||||
|
||||
**`Move{unk=…, unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose. But probably moves the character to a specified position.
|
||||
|
||||
**`WaitForMove()`**
|
||||
|
||||
Unknown purpose. But probably waits until the character has stopped moving.
|
||||
|
||||
## Class `Actor`
|
||||
|
||||
**`EndEventRollback{unk=…, unk=…}`**
|
||||
|
||||
Unknown purpose.
|
17
content/concept/game-masters.md
Normal file
17
content/concept/game-masters.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
title: "Game Masters"
|
||||
---
|
||||
|
||||
These are moderators in the game, and can be called upon when reporting a player. To carry out their tasks, they are given access to special commands not available to normal players. If a normal player attempts to use a command, nothing happens - the client won't even send it unless they have a GM rank.
|
||||
|
||||
# Ranks
|
||||
|
||||
There is not a single "rank" or "level" of GM, but in fact several. This probably mirrors the same structure seen in XI, where there are Junior GMs lead by one or more senior GMs. There are also event GMs?
|
||||
|
||||
# Commands
|
||||
|
||||
Since we don't have access to any documentation to what these commands do, the purpose and usage are guesswork.
|
||||
|
||||
| Command | Description |
|
||||
| --- | --- |
|
||||
| `//gm invis` | Turns the current player invisible. |
|
|
@ -2,7 +2,7 @@
|
|||
title: "Logging into Official Servers"
|
||||
---
|
||||
|
||||
{{< note "This only covers logging in via non-Steam Square Enix accounts right now." >}}
|
||||
{{< info "This only covers logging in via non-Steam Square Enix accounts right now." >}}
|
||||
|
||||
Logging into the official FFXIV servers is actually very simple, and all you need is the ability to send/receive HTTP requests, parse JSON responses and read some files off of the disk.
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
title: "Logging into Sapphire Servers"
|
||||
---
|
||||
|
||||
[Sapphire](https://github.com/SapphireServer/Sapphire/) has a much, much easier login process than [the official servers]({{< ref "concept/logging-in-official" >}}), which only consist of one or two requests.
|
||||
|
||||
# Logging in
|
||||
|
||||
**POST** `http(s)://{sapphire_lobby_url}/sapphire-api/lobby/login`
|
||||
|
||||
You'll need to construct a JSON body as follows:
|
||||
|
||||
```
|
||||
{
|
||||
"username": {username},
|
||||
"pass": {pass}
|
||||
}
|
||||
```
|
||||
|
||||
Of course, `{username}` and `{password}` is the user account credentials.
|
||||
|
||||
The response is also JSON, and if it's not empty (which indicates a login error) it will be constructed like this:
|
||||
|
||||
```
|
||||
{
|
||||
"sId": {SID},
|
||||
"lobbyHost": {lobby_host},
|
||||
"frontierHost": {frontier_host}
|
||||
}
|
||||
```
|
||||
|
||||
Now you can launch the game! See [ffxiv.exe](executable/ffxiv) for more arguments. For a quick rundown:
|
||||
* Set `DEV.TestSID` to `{SID}`.
|
||||
* Set `DEV.MaxEntitledExpansionID` to your desired expansion level.
|
||||
* Set `SYS.Region` to 3.
|
||||
* Set `DEV.GMServerHost` to `{frontier_host}`.
|
||||
* Set `DEV.LobbyHost01`...`DEV.LobbyHost09` to `{lobby_host}`.
|
||||
* Set `DEV.LobbyPort01`...`DEV.LobbyPort09` to your Sapphire lobby's port - usually 54994.
|
||||
|
||||
# Registering an account
|
||||
|
||||
**POST** `http(s)://{sapphire_lobby_url}/sapphire-api/lobby/createAccount`
|
||||
|
||||
This request is identical to the one used for logging in, so refer to the section above for details.
|
5
content/concept/logical-data-center.md
Normal file
5
content/concept/logical-data-center.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "Logical Data Center"
|
||||
---
|
||||
|
||||
These are data centers.
|
24
content/concept/packets.md
Normal file
24
content/concept/packets.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
title: "Packets"
|
||||
---
|
||||
|
||||
Communication between the [client]({{< ref "ffxiv" >}}) and Servers happen with custom, binary packet structures sent over [TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol).
|
||||
|
||||
# Packets
|
||||
|
||||
Each packet begins with a header, that is always the same size and is never encrypted or compressed:
|
||||
|
||||
```rust
|
||||
struct PacketHeader {
|
||||
unk1: u64, /// Unknown value
|
||||
unk2: u64, /// Another unknown value
|
||||
timestamp: u64, /// Milliseconds since UNIX epoch
|
||||
size: u32, /// Total size of the packet *INCLUDING* this header
|
||||
connection_type: ConnectionType, /// The connection this happened on
|
||||
segment_count: u16, /// How many segments follow this header
|
||||
unk3: u8, /// Yet another unknown value
|
||||
compression_type: CompressionType, /// The type of compression used for segment data
|
||||
unk4: u16, /// Whoop, more unknowns
|
||||
uncompressed_size: u32, /// If compressed, the size of the data when uncompressed. Otherwise, always 0.
|
||||
}
|
||||
```
|
|
@ -8,14 +8,14 @@ This is the "encrypted argument" format used by a lot of FFXIV programs and is u
|
|||
|
||||
When viewing the command line arguments for, say [ffxiv.exe](executable/ffxiv) you will see it's only something like this:
|
||||
|
||||
```
|
||||
```shell
|
||||
//**sqex0003S2_Utl8qdamv3_82SH7Lhtk=S**//
|
||||
```
|
||||
_(Yes, I did garble some of the text, so it's not actually decodable :-))_
|
||||
|
||||
There are three distinct parts of this string:
|
||||
|
||||
```
|
||||
```shell
|
||||
//**sqex0003S2_Utl8qdamv3_82SH7Lhtk=S**//
|
||||
^^ ^
|
||||
version|| |
|
||||
|
@ -51,7 +51,7 @@ The resulting bytes when you decode the base64 string is going to Blowfish ECB e
|
|||
|
||||
The key used for encrypting/decrypting the encrypted arguments is just your **system's uptime clock**. All FFXIV executables just call `GetTickCount()`, and theres about ~50 or so ticks of freedom before the game or launcher considers it invalid. There is a specific transformation you need to do in order to fetch a valid key though:
|
||||
|
||||
```
|
||||
```cpp
|
||||
unsigned int rawTicks = TickCount();
|
||||
unsigned int ticks = rawTicks & 0xFFFFFFFFu;
|
||||
unsigned int key = ticks & 0xFFFF0000u;
|
||||
|
@ -64,7 +64,7 @@ To make this easier, here is a couple of platform-specific implementations of `T
|
|||
|
||||
### Windows
|
||||
|
||||
```
|
||||
```cpp
|
||||
uint32_t TickCount() {
|
||||
return GetTickCount();
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ uint32_t TickCount() {
|
|||
|
||||
### macOS
|
||||
|
||||
```
|
||||
```cpp
|
||||
uint32_t TickCount() {
|
||||
struct mach_timebase_info timebase;
|
||||
mach_timebase_info(&timebase);
|
||||
|
@ -87,7 +87,7 @@ uint32_t TickCount() {
|
|||
|
||||
### Linux
|
||||
|
||||
```
|
||||
```cpp
|
||||
uint32_t TickCount() {
|
||||
struct timespec ts;
|
||||
|
||||
|
@ -102,7 +102,7 @@ uint32_t TickCount() {
|
|||
If you're just interested in decrypting game arguments, this is not essential. This is presumably used as a checksum
|
||||
when the game checks your encrypted string.
|
||||
|
||||
```
|
||||
```cpp
|
||||
static char ChecksumTable[] = {
|
||||
'f', 'X', '1', 'p', 'G', 't', 'd', 'S',
|
||||
'5', 'C', 'A', 'P', '4', '_', 'V', 'L'
|
||||
|
|
3
content/dalamud/_index.md
Normal file
3
content/dalamud/_index.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
title: "Dalamud"
|
||||
---
|
20
content/dalamud/dalamud-plugin-dev.md
Normal file
20
content/dalamud/dalamud-plugin-dev.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: "Building Dalamud plugins on Linux"
|
||||
---
|
||||
|
||||
It's trivial to develop Dalamud plguins on Linux since they moved to .NET Core!
|
||||
|
||||
# The .NET SDK
|
||||
|
||||
You need the .NET SDK of course, which is already in many package managers:
|
||||
|
||||
* Fedora Linux: `dotnet`
|
||||
* Arch Linux: `dotnet-sdk`
|
||||
* Gentoo Linux: `dotnet-sdk` or `dotnet-sdk-bin`
|
||||
|
||||
Currently Dalamud requires .NET 9.0 as of API 12.
|
||||
|
||||
# devPlugin path
|
||||
|
||||
Remember that when entering the dev plugin path in the Dalamud settings, to prepend it with `Z:` and take care of your slashes so they make sense under Wine.
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
title: "Creating your own Dalamud repository"
|
||||
---
|
||||
|
||||
{{< note "This is for creating a 3rd party repository, which is probably not what you want. Almost all plugins should be submitted to the main repository, see https://dalamud.dev/plugin-development/plugin-submission." >}}
|
||||
{{< info "This is for creating a 3rd party repository, which is probably not what you want. Almost all plugins should be submitted to the main repository, see https://dalamud.dev/plugin-development/plugin-submission." >}}
|
||||
|
||||
Creating a 3rd party Dalamud repository is easy, since it's pretty stateless and only requires you to host the files somewhere. People even host them on free servers like GitHub.
|
||||
Creating a 3rd party Dalamud repository is easy, because it's stateless and can be on any publicly accessible static location on the web.
|
||||
|
||||
# Plugin Manifests
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
title: "Benchmarks"
|
||||
---
|
||||
|
||||
There have been several benchmarks publicly released, which are [modified client executables](/executable/ffxiv) that replay several cutscenes (usually made exclusively for the benchmark) and can create character creation save data.
|
||||
There have been several benchmarks publicly released, which are [modified client executables]({{< ref "executable/ffxiv" >}}) that play several cutscenes in sequence (usually made exclusively for the benchmark) and can create [character creation save data]({{< ref "chardat" >}}).
|
||||
|
||||
Despite the [official FFXIV Benchmark site](https://na.finalfantasyxiv.com/benchmark/) only displaying the latest expansion, all previous benchmarks are still accessible. An archive of all links are provided below.
|
||||
Despite the [official FFXIV Benchmark site](https://na.finalfantasyxiv.com/benchmark/) only displaying the latest expansion, previous benchmarks are still accessible. An archive of all links are provided below.
|
||||
|
||||
* [Original (1.x)](http://http.download.nvidia.com/downloads/nZone/demos/FFXIVBenchmark.zip)
|
||||
* [A Realm Reborn (2.x)](http://download.finalfantasyxiv.com/inst/FFXIV-ARR-Bench-Character.zip)
|
||||
|
@ -14,4 +14,4 @@ Despite the [official FFXIV Benchmark site](https://na.finalfantasyxiv.com/bench
|
|||
* [Endwalker (6.x)](https://download.finalfantasyxiv.com/ys8glaimvmykn88p/ffxiv-endwalker-bench.zip)
|
||||
* [Dawntrail (7.x)](https://download.finalfantasyxiv.com/s9qmq6SJfMMqYM4o/ffxiv-dawntrail-bench.zip)
|
||||
|
||||
{{< note "ARR and Heavenward place the benchmark files under a `/inst` directory on their server. Expansions afterward, place it under a directory with a directory with a seemingly randomized string such as 'nr2xkhecw9vrkuqy'." >}}
|
||||
{{< info "ARR and Heavenward place the benchmark files under a `/inst` directory on their server. Expansions afterward, place it under a directory with a directory with a seemingly randomized string such as 'nr2xkhecw9vrkuqy'." >}}
|
||||
|
|
|
@ -4,11 +4,11 @@ title: "Client (ffxiv.exe)"
|
|||
|
||||
This is the game client executable.
|
||||
|
||||
{{< note "There are two separate executables for DirectX 11 and DirectX 9. The DX11 version is named `ffxiv_dx11.exe`. The DX9 version will be removed in a future update." >}}
|
||||
{{< info "There was two separate executables for DirectX 11 and DirectX 9. The DX11 version is named `ffxiv_dx11.exe`. The DX9 version was removed and is no longer in the retail release." >}}
|
||||
|
||||
# Arguments
|
||||
|
||||
{{< info "Unlike other executables, passing arguments encrypted with SqexArg is optional for the client. It's recommended that you do so if you're planning to use actual SIDs though." >}}
|
||||
{{< note "Unlike other executables, passing arguments encrypted with SqexArg is optional for the client. It's recommended that you do so if you're planning to use actual SIDs though." >}}
|
||||
|
||||
There a few known arguments that work on the normal game client:
|
||||
|
||||
|
|
|
@ -10,24 +10,24 @@ The program that processes the [patch files]({{< ref "format/patch" >}}) and app
|
|||
|
||||
{{< note "Just like the other executables, it requires you to pass these using the [SqexArg](concept/sqexarg) format." >}}
|
||||
|
||||
- BootVersion
|
||||
- `BootVersion`
|
||||
- The version of the boot component.
|
||||
- GameVersion
|
||||
- `GameVersion`
|
||||
- The version of the game component, however I'm curious as to the purpose of this variable. Is the patcher itself fetching the patches required for the provided game version?
|
||||
- CallerWindow
|
||||
- `CallerWindow`
|
||||
- This seems to be the HWND which it sends messages to. Passing a HWND that is setup to receive messages, it appears to yield a 0x74 message (OpenWindow I believe) which means this is the most likely case. More on the IPC below.
|
||||
- IsSteam
|
||||
- `IsSteam`
|
||||
- Obviously, to check if this is the Steam version. I have not reversed the game arguments of the Steam version yet.
|
||||
- NextExe
|
||||
- `NextExe`
|
||||
- I'm not entirely sure what the purpose of this is yet. It makes no sense for the updater to call the game itself, I'm pretty sure this is used for "patch chaining" but it's
|
||||
also set for regular game patches. For example, when updating the game through the launcher it points to ffxiv.exe. Note that it is not ffxiv_dx11.exe, which means this is
|
||||
probably unused in the retail launcher.
|
||||
- ShowMode
|
||||
- `ShowMode`
|
||||
- This is the most interesting parameter, more testing is needed. There is multiple values here, and some of them correspond to known launcher behavior:
|
||||
- 1: This seems to be some sort of standalone updater window that I've never seen before in retail. Is this a leftover from a older version of the game? For example, it looks for "LauncherPatchInstall.list" (I can't seem to recreate this file). I have not gotten it to read from a "GamePatchInstall.list" either, however there is probably some other parameter to trigger this change. This "list" format is also unknown.
|
||||
- 2: This has no user-visible window, and is the "default mode" when launched properly through ffxivlauncher.exe. It's communicating through regular Win32 IPC I believe, back to the launcher where the launcher updates it's own window.
|
||||
- 3: I haven't gotten this mode to work, but on the standalone updater window it mentions "repairing game files". I believe this is what's used by the "repair game files" button in the launcher, but I've never used it before nor do I know it's actual purpose (just checking hashes?).
|
||||
- UserPath
|
||||
- `UserPath`
|
||||
- This is the usual UserPath arugment, pointing to your FFXIV-ARR Documents directory.
|
||||
|
||||
# Processes
|
||||
|
|
|
@ -39,4 +39,4 @@ The rest of the file is the Havok binary tagfile format which you will probably
|
|||
|
||||
# Alternative Implementations
|
||||
|
||||
None yet.
|
||||
* Physis (Rust)
|
||||
|
|
|
@ -4,9 +4,7 @@ title: "Frontier"
|
|||
|
||||
{{< note "This documentation is incomplete." >}}
|
||||
|
||||
This is a multi-purpose server, and seems to handle many miscellaneous aspects.
|
||||
|
||||
It serves the [launcher](/executable/ffxivlauncher) page and gives out the gate status, for example.
|
||||
This is a multi-purpose server, and seems to handle many miscellaneous aspects. It serves the [launcher](/executable/ffxivlauncher) page and informs the client of whether they can login, for example. It also serves news and the current banner images too.
|
||||
|
||||
# Alternative Implementations
|
||||
|
||||
|
|
|
@ -2,8 +2,34 @@
|
|||
title: "Lobby"
|
||||
---
|
||||
|
||||
{{< note "This documentation is incomplete." >}}
|
||||
These servers are first thing the [game client]({{< ref "executable/ffxiv" >}}) connects to when you login. These are the ones hardcoded into the client:
|
||||
|
||||
* neolobby01.ffxiv.com (Elemental) (`LobbyHost01`)
|
||||
* neolobby03.ffxiv.com (Gaia) (`LobbyHost02`)
|
||||
* neolobby05.ffxiv.com (Mana) (`LobbyHost03`)
|
||||
* neolobby02.ffxiv.com (Aether) (`LobbyHost04`)
|
||||
* neolobby04.ffxiv.com (Primal) (`LobbyHost05`)
|
||||
* neolobby06.ffxiv.com (Chaos) (`LobbyHost06`)
|
||||
* neolobby07.ffxiv.com (Light) (`LobbyHost07`)
|
||||
* neolobby08.ffxiv.com (Crystal) (`LobbyHost08`)
|
||||
* neolobby09.ffxiv.com (Materia) (`LobbyHost09`)
|
||||
* neolobby10.ffxiv.com (Meteor) (`LobbyHost10`)
|
||||
* neolobby11.ffxiv.com (Dynamis) (`LobbyHost11`)
|
||||
* neolobby12.ffxiv.com (Shadow[^1]) (`LobbyHost12`)
|
||||
* neolobby98.ffxiv.com (Unknown[^2]) (`LobbyHost98`)
|
||||
|
||||
These directly correspond to the layout of the [Logical Data Centers]({{< ref "logical-data-center" >}}). And this makes sense, as the lobby server you connect to changes depending on which logical data center you select in the client.
|
||||
|
||||
The main purpose of the lobby is to funnel you to [the World server]({{< ref "world" >}}) of your choosing. It also acts as a waiting area during congestion, putting players into a queue before connecting to the World server.
|
||||
|
||||
Communication with the Lobby server is "encrypted", which is strange as the rest of the game's communication isn't. Another interesting thing is that the client doesn't have the IP address of the World servers hardcoded, but this is instead given to the client by the Lobby server on login.
|
||||
|
||||
# Alternative Implementations
|
||||
|
||||
* [Sapphire (C++)](https://github.com/SapphireServer/Sapphire/)
|
||||
* Maelstorm (C#)
|
||||
* iolite (Rust)
|
||||
* Kawari (Rust)
|
||||
|
||||
[^1]: The Shadow data center [is defunct](https://gamerant.com/final-fantasy-14-servers-shutdown-shadow-data-center/).
|
||||
[^2]: It's likely because of the high number - chosen to avoid conflicts with any future datacenter additions - that is meant for public testing. And indeed, this was the lobby server for the NA Cloud DC test.
|
||||
|
|
|
@ -4,6 +4,8 @@ title: "Patch"
|
|||
|
||||
These servers provide patch files that are consumed by the [patcher](/executable/ffxivupdater) and the [boot](/executable/ffxivboot) executables.
|
||||
|
||||
The Patch server also checks if the hashes of the client files are valid, but the Lobby server does this in addition.
|
||||
|
||||
## Console updating
|
||||
|
||||
The PS3 and PS4 versions of the game used to use the same patch system as the Windows version. That changed [in 2018 when Square Enix moved to updating through PSN](https://na.finalfantasyxiv.com/lodestone/news/detail/2b63219b37d83601618341b5a7876d9a6c72a774). Trying to contact the patch servers with PS4 patch requests will return a 404. And of course since the PS3 version is defunct, that also doesn't work.
|
||||
|
|
|
@ -2,8 +2,17 @@
|
|||
title: "World"
|
||||
---
|
||||
|
||||
{{< note "This documentation is incomplete." >}}
|
||||
This is the main server that communicates the minute-to-minute gameplay.
|
||||
|
||||
Unlike other servers, the opcodes for the World server are randomized each patch. This was done starting in Shadowbringers(?)[^1] to prevent the usage of client-side tools like ACT, although this didn't actually change anything.
|
||||
|
||||
Communication with the World server is compressed with [Oodle](https://www.radgametools.com/oodle.htm). It was previously compressed with Zlib until Patch 6.3. Compression is optional however, the client happily accepts uncompressed packets.
|
||||
|
||||
# Alternative Implementations
|
||||
|
||||
* [Sapphire (C++)](https://github.com/SapphireServer/Sapphire/)
|
||||
* Maelstorm (C#)
|
||||
* iolite (Rust)
|
||||
* Kawari (Rust)
|
||||
|
||||
[^1]: Alluded to in this [Sapphire Blog post](https://sapphireserver.github.io/dev/2019/12/23/fixing-opcodes.html)
|
||||
|
|
|
@ -163,3 +163,7 @@ footer {
|
|||
.info p {
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
article {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<html lang="{{ .Site.LanguageCode }}" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
{{- partial "head.html" . -}}
|
||||
<body>
|
||||
<header>{{- partial "header.html" . -}}</header>
|
||||
<div id="content">
|
||||
<aside>{{- partial "sidebar.html" . -}}</aside>
|
||||
<article>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<footer>
|
||||
<a href="https://xiv.zone">xiv.zone</a>
|
||||
<a href="https://xiv.zone/copyright">Copyright Notice</a>
|
||||
<a href="https://github.com/redstrate/docs.xiv.zone">Source Code</a>
|
||||
</footer>
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
{{ $current := . }}
|
||||
{{ template "tree-nav" dict "sect" .Site.Home.Sections "current" $current }}
|
||||
{{ template "tree-nav" dict "sect" .Site.Home.Sections "current" $current "top" $current }}
|
||||
|
||||
{{ define "tree-nav" }}
|
||||
{{ $current := .current }}
|
||||
|
||||
|
||||
<ul class="gdoc-nav__list">
|
||||
{{ if .top }}
|
||||
<li><a href="/">Home</a></li>
|
||||
{{ end }}
|
||||
|
||||
{{ $sortBy := (default "title" | lower) }}
|
||||
{{ range .sect.GroupBy "Weight" }}
|
||||
{{ $rangeBy := .ByTitle }}
|
||||
|
|
Loading…
Add table
Reference in a new issue