Skip to content

Commit df8e674

Browse files
authored
docs: add line 41 documentation (quisquous#4199)
1 parent cd7aed7 commit df8e674

File tree

5 files changed

+86
-20
lines changed

5 files changed

+86
-20
lines changed

docs/LogGuide.md

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,12 @@ ACT Log Line Examples:
18601860

18611861
### Line 41 (0x29): SystemLogMessage
18621862

1863-
This log line is sent when there are system log messages:
1863+
This log line is sent when there are system log messages.
1864+
As game chat log lines are read from memory in the FFXIV ACT plugin,
1865+
[Line 41](#line41) can be sent both before or after the corresponding [Line 00](#line00).
1866+
That said, they are usually sequential in the network log,
1867+
and so there is no timing advantage to using one over the other,
1868+
but the system log message will have a correct timestamp.
18641869

18651870
```log
18661871
[10:38:40.066] SystemLogMessage 29:00:901:619A9200:00:3C
@@ -1873,30 +1878,26 @@ This log line is sent when there are system log messages:
18731878
[10:55:06.707] SystemLogMessage 29:8004001E:B3A:00:00:E0000000
18741879
```
18751880

1876-
TODO: write a better explanation here and understand these parameters.
1877-
It'd be nice to figure out what these mean so we could replace
1878-
zone closing and npc dialog with these lines.
1879-
18801881
<!-- AUTO-GENERATED-CONTENT:START (logLines:type=SystemLogMessage&lang=en-US) -->
18811882

18821883
#### Structure
18831884

18841885
```log
18851886
Network Log Line Structure:
1886-
41|[timestamp]|[?]|[id]|[param0]|[param1]|[param2]
1887+
41|[timestamp]|[instance]|[id]|[param0]|[param1]|[param2]
18871888
18881889
ACT Log Line Structure:
1889-
[timestamp] SystemLogMessage 29:[?]:[id]:[param0]:[param1]:[param2]
1890+
[timestamp] SystemLogMessage 29:[instance]:[id]:[param0]:[param1]:[param2]
18901891
```
18911892

18921893
#### Regexes
18931894

18941895
```log
18951896
Network Log Line Regex:
1896-
^(?<type>(?:41))\|(?<timestamp>(?:[^|]*))\|(?:[^|]*\|)(?<id>(?:[^|]*))\|(?<param0>(?:[^|]*))\|(?<param1>(?:[^|]*))\|(?<param2>(?:[^|]*))\|
1897+
^(?<type>(?:41))\|(?<timestamp>(?:[^|]*))\|(?<instance>(?:[^|]*))\|(?<id>(?:[^|]*))\|(?<param0>(?:[^|]*))\|(?<param1>(?:[^|]*))\|(?<param2>(?:[^|]*))\|
18971898
18981899
ACT Log Line Regex:
1899-
(?<timestamp>^.{14}) SystemLogMessage (?<type>29):[^:]*:(?<id>(?:[^:]*)):(?<param0>(?:[^:]*)):(?<param1>(?:[^:]*)):(?<param2>(?:[^:]*))(?:$|:)
1900+
(?<timestamp>^.{14}) SystemLogMessage (?<type>29):(?<instance>(?:[^:]*)):(?<id>(?:[^:]*)):(?<param0>(?:[^:]*)):(?<param1>(?:[^:]*)):(?<param2>(?:[^:]*))(?:$|:)
19001901
```
19011902

19021903
#### Examples
@@ -1915,6 +1916,67 @@ ACT Log Line Examples:
19151916

19161917
<!-- AUTO-GENERATED-CONTENT:END -->
19171918

1919+
The `instance` parameter is identical to `instance` in [actor control line)](#line33).
1920+
The first two bytes are the update type
1921+
and the second two bytes are ids in the [InstanceContent table](https://github.com/xivapi/ffxiv-datamining/blob/master/csv/InstanceContent.csv).
1922+
1923+
The `id` parameter is an id into the [LogMessage table](https://github.com/xivapi/ffxiv-datamining/blob/master/csv/LogMessage.csv).
1924+
1925+
id (hex) | Link | Shortened Message
1926+
--- | --- | ---
1927+
0x2EE | [link](https://xivapi.com/LogMessage/750?pretty=true) | You obtain (an item)
1928+
0x7DC | [link](https://xivapi.com/LogMessage/2012?pretty=true) | will be sealed off in X seconds
1929+
0x7DD | [link](https://xivapi.com/LogMessage/2013?pretty=true) | is sealed off
1930+
0x7DE | [link](https://xivapi.com/LogMessage/2014?pretty=true) | is no longer sealed
1931+
1932+
The log message itself determines the other parameters.
1933+
It seems that `IntegerParameter(1)` in the log message corresponds to `param1`
1934+
and `IntegerParameter(2)` corresponds to `param2`.
1935+
It is not clear what `param0` does or how other `Parameter` functions work.
1936+
1937+
Here are two network log lines:
1938+
1939+
```log
1940+
41|2022-01-11T16:28:50.6340000-08:00|80030054|7DC|02|1008|0F|1a1b91bd4bf5d5e1^M
1941+
00|2022-01-11T16:28:50.0000000-08:00|0839||The shell mound will be sealed off in 15 seconds!|3a0befeef04e203b^M
1942+
```
1943+
1944+
`80030054` is the instance.
1945+
`8003` means instanced content.
1946+
(`8004` means trust content.)
1947+
`0054` is the [InstanceContent](https://xivapi.com/InstanceContent/84?pretty=true) id,
1948+
so this is The Dead Ends.
1949+
1950+
`7DC` is the `id`, which [corresponds](https://xivapi.com/LogMessage/2012?pretty=true) to:
1951+
`"<Clickable(<SheetEn(PlaceName,2,IntegerParameter(1),2,1)\/>)\/> will be sealed off in <Value>IntegerParameter(2)<\/Value> <If(Equal(IntegerParameter(2),1))>second<Else\/>seconds<\/If>!"`
1952+
1953+
Use the log message itself to determine what `param1` and `param2` mean, if anything.
1954+
1955+
In this case,
1956+
`param1` is `1008`, which from the log message you can determine is a PlaceName id.
1957+
Looking this up in the [PlaceName](https://xivapi.com/PlaceName/4104?pretty=true) table gets "Shell Mound".
1958+
1959+
`param2` is `0x0F`, which from the log message is used for the seconds in the message, i.e. 15 in decimal.
1960+
1961+
Here's one other example:
1962+
1963+
```log
1964+
41|2022-02-18T22:03:00.5130000-08:00|1B01EA|2EE|C2BD6401|758A|45D530|9efb90e26e3b41c3
1965+
00|2022-02-18T22:03:00.0000000-08:00|0BBE||You obtain a little leafman.|51d9427a6354d3af
1966+
```
1967+
1968+
`2EE` is the `id`, which [corresponds](https://xivapi.com/LogMessage/750?pretty=true) to:
1969+
`"<Clickable(<If(Equal(ObjectParameter(1),ObjectParameter(2)))>you<Else/><If(PlayerParameter(7))><SheetEn(ObjStr,2,PlayerParameter(7),1,1)/><Else/>ObjectParameter(2)</If></If>)/> <If(Equal(ObjectParameter(1),ObjectParameter(2)))>obtain<Else/>obtains</If> <SheetEn(Item,1,IntegerParameter(1),1,1)/>."`
1970+
1971+
Here, `param1` is `758A`, which [corresponds](https://xivapi.com/Item/30090?pretty=true) to "Little Leafman" in the `Item` table.
1972+
It is unclear how `ObjectParameter` and `PlayerParameter` work here.
1973+
1974+
Future work:
1975+
1976+
- What is `param0`? Is it just skipped?
1977+
- How do `PlayerParameter` and `ObjectParameter` work in the `LogMessage` table?
1978+
- Some log messages don't show as 41 lines, e.g. "You have arrived at a vista" or "Engage!".
1979+
19181980
<a name="line251"></a>
19191981

19201982
### Line 251 (0xFB): Debug

resources/netlog_defs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ const logDefinitions = {
728728
fields: {
729729
type: 0,
730730
timestamp: 1,
731-
// unknown: 2,
731+
instance: 2,
732732
id: 3,
733733
param0: 4,
734734
param1: 5,

test/unittests/netregex_test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -379,11 +379,12 @@ describe('netregex tests', () => {
379379
] as const;
380380
regexCaptureTest((params?: RegexUtilParams) => NetRegexes.systemLogMessage(params), lines);
381381

382-
const matches = lines[0].match(NetRegexes.systemLogMessage())?.groups;
382+
const matches = lines[1].match(NetRegexes.systemLogMessage())?.groups;
383383
assert.equal(matches?.type, '41');
384-
assert.equal(matches?.id, '901');
385-
assert.equal(matches?.param0, '619A9200');
386-
assert.equal(matches?.param1, '00');
387-
assert.equal(matches?.param2, '3C');
384+
assert.equal(matches?.instance, '8004001E');
385+
assert.equal(matches?.id, '7DD');
386+
assert.equal(matches?.param0, 'FF5FDA02');
387+
assert.equal(matches?.param1, 'E1B');
388+
assert.equal(matches?.param2, '00');
388389
});
389390
});

test/unittests/regex_test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,11 @@ describe('regex tests', () => {
390390
] as const;
391391
regexCaptureTest((params?: RegexUtilParams) => Regexes.systemLogMessage(params), lines);
392392

393-
const matches = lines[0].match(Regexes.systemLogMessage())?.groups;
394-
assert.equal(matches?.id, '901');
395-
assert.equal(matches?.param0, '619A9200');
396-
assert.equal(matches?.param1, '00');
397-
assert.equal(matches?.param2, '3C');
393+
const matches = lines[1].match(Regexes.systemLogMessage())?.groups;
394+
assert.equal(matches?.instance, '8004001E');
395+
assert.equal(matches?.id, '7DD');
396+
assert.equal(matches?.param0, 'FF5FDA02');
397+
assert.equal(matches?.param1, 'E1B');
398+
assert.equal(matches?.param2, '00');
398399
});
399400
});

ui/raidboss/emulator/data/network_log_converter/LineEvent0x29.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const fields = logDefinitions.SystemLogMessage.fields;
77

88
// SystemLogMessage event
99
export class LineEvent0x29 extends LineEvent {
10+
public readonly instance: string;
1011
public readonly id: string;
1112
public readonly param0: string;
1213
public readonly param1: string;
@@ -15,6 +16,7 @@ export class LineEvent0x29 extends LineEvent {
1516
constructor(repo: LogRepository, line: string, parts: string[]) {
1617
super(repo, line, parts);
1718

19+
this.instance = parts[fields.instance] ?? '';
1820
this.id = parts[fields.id] ?? '';
1921
this.param0 = parts[fields.param0] ?? '';
2022
this.param1 = parts[fields.param1] ?? '';

0 commit comments

Comments
 (0)