|
| 1 | +# Reporting a problem |
| 2 | + |
| 3 | +How "it works for you and not for me" gets answered without anybody sending |
| 4 | +their `Game.log` anywhere. |
| 5 | + |
| 6 | +Settings → **Report a problem** saves a small JSON file. This is what is in it, |
| 7 | +what is deliberately not, and the one thing it cannot promise. |
| 8 | + |
| 9 | +## Why not just send the log |
| 10 | + |
| 11 | +Three reasons, in order of how quickly they bite. |
| 12 | + |
| 13 | +**Size.** A quiet session here is 0.2 MB. A real one is **8.1 MB and 29,269 |
| 14 | +lines**. The whole corpus on this machine is **158 files, 435 MB**. Pastebin |
| 15 | +refuses a paste over 512 KB on a free account, so almost every gameplay log is |
| 16 | +too big before privacy is even discussed. GitHub accepts a 25 MB attachment, |
| 17 | +which fits one log and not a set. |
| 18 | + |
| 19 | +**Other people.** A log names the pilots you flew with. Party notifications and |
| 20 | +ship comms channels are the only lines in a 4.x log that name another player — |
| 21 | +they are the entire basis of the Crew page — so publishing your log publishes |
| 22 | +their handles too. That is not yours to give away. |
| 23 | + |
| 24 | +**Yours.** The header carries your handle, character GEID, account id and |
| 25 | +session GUIDs, and `Executable:` names a user folder on many installs. |
| 26 | + |
| 27 | +## What the report holds instead |
| 28 | + |
| 29 | +The parser already records what it could not read: a count per unrecognised tag |
| 30 | +and one example line each (`LogEventParser.RecordUnmatched`). That is the whole |
| 31 | +diagnosis for an empty page, and it is **kilobytes** — a real report from this |
| 32 | +install is about 1 KB. |
| 33 | + |
| 34 | +| Field | Why it is in there | |
| 35 | +|---|---| |
| 36 | +| `producer` | App version and build, so the answer is about the right code | |
| 37 | +| `install` | Whether an install was found, its channel, whether `Game.log` is present, how many backups — **never the path** | |
| 38 | +| `library` | Sessions stored and counted, first and last dates, and every game build seen with a count | |
| 39 | +| `parser` | How many lines went unread this run, and under which tags | |
| 40 | +| `views` | The counts behind each page — ships, places, contracts, purchases, trades, fleet, loadout, stash | |
| 41 | +| `data` | Whether the community dataset and UEX are on, and which dump the dataset came from | |
| 42 | +| `wipe` | The line, its scope, and how many sessions sit before it | |
| 43 | + |
| 44 | +`views` and `wipe` are there because most "this page is empty" reports are not |
| 45 | +parser bugs at all. A Crew page with nothing on it and a `wipe.hidden` of 108 is |
| 46 | +a wipe line drawn too late, not a defect. |
| 47 | + |
| 48 | +## Allow-list, not deny-list |
| 49 | + |
| 50 | +Every field above is one the code chose to put in. The report is **built up** |
| 51 | +from facts the app can name, rather than **built down** from a log with the |
| 52 | +private parts stripped out. |
| 53 | + |
| 54 | +That direction is the whole safety argument. A deny-list leaks the pattern |
| 55 | +nobody thought of, and the only thing worse than no report is one that promises |
| 56 | +to be clean and is not. It is the same reasoning as `LanGuard`, which whitelists |
| 57 | +read methods rather than listing forbidden endpoints. |
| 58 | + |
| 59 | +Consequences worth stating: |
| 60 | + |
| 61 | +- **The install path is absent.** It reads `C:\Users\<name>\...` on plenty of |
| 62 | + machines, and it has never been the answer to a parser question. |
| 63 | +- **UEX keys are absent.** Whether keys are *stored* is a boolean, because "UEX |
| 64 | + is on but has no keys" explains a page of blanks. |
| 65 | +- **No handle, character or account id appears anywhere.** |
| 66 | + |
| 67 | +A test reads the whole document back and fails if any field is so much as |
| 68 | +*named* for one of those, so a field added later that carries one arrives as a |
| 69 | +red test rather than a quiet leak. |
| 70 | + |
| 71 | +## The one thing it cannot promise |
| 72 | + |
| 73 | +Example lines are **off unless you ask**, and this is why. |
| 74 | + |
| 75 | +A sample exists only because a known tag stopped parsing — which means the |
| 76 | +game changed that line's format. A changed format is free to write your name in |
| 77 | +a shape nothing here has ever seen. Scrubbing replaces the identifiers this |
| 78 | +install has already read, and the shapes the game has always used |
| 79 | +(`Handle[...]`, `nickname="..."`, `- name X -`, GEIDs, account ids, session |
| 80 | +GUIDs). It cannot replace a shape that has just been invented. |
| 81 | + |
| 82 | +That is not a hypothetical. A synthetic 4.11-shaped log whose login line was |
| 83 | +reshaped to `Pilot{TestPilot42}` came through the scrubber **still naming its |
| 84 | +pilot**: |
| 85 | + |
| 86 | +``` |
| 87 | +2 Legacy login response [CIG-net] User Login OK - Pilot{TestPilot42} - Time[177332566] |
| 88 | +2 AccountLoginCharacterStatus_Character Character: createdAt 1784476187540 - geid <id> - accountId <id> - name <pilot> - status CURRENT |
| 89 | +2 Context Establisher Done establisher="Game" nonsense session=<session> |
| 90 | +``` |
| 91 | + |
| 92 | +Two of the three were scrubbed because their shapes were known. The one that |
| 93 | +was not is the one whose format had changed — and a format change is the only |
| 94 | +reason any of them is in the list. |
| 95 | + |
| 96 | +There is a second, quieter failure in the same case: when the line that broke is |
| 97 | +the *login* line, the handle never reaches the session store, so there is no |
| 98 | +value to search for either. Shape-based scrubbing is what covers that, and it |
| 99 | +covers only shapes it knows. |
| 100 | + |
| 101 | +So the report always carries the **counts**, which are safe by construction and |
| 102 | +enough to see that something broke and where. The **lines** are a separate yes, |
| 103 | +and the Settings page says plainly what it cannot promise about them. |
| 104 | + |
| 105 | +## Sending one |
| 106 | + |
| 107 | +Nothing is uploaded. The file is built in the page and handed to the browser, |
| 108 | +so it lands in your downloads and goes no further until you send it. Read it |
| 109 | +first — it is a kilobyte of JSON and that is the point of it being small. |
| 110 | + |
| 111 | +Attach it to a GitHub issue with what you expected to see and what you saw. |
| 112 | + |
| 113 | +## Reading one, as a maintainer |
| 114 | + |
| 115 | +In roughly this order: |
| 116 | + |
| 117 | +1. **`parser.unread`.** Anything above zero with a tag list is a format change: |
| 118 | + the game moved a line the app depends on. Ask for the example lines if they |
| 119 | + are not attached. |
| 120 | +2. **`library.builds`.** Which patch they are on, and whether the sessions are |
| 121 | + spread across several. A build nobody else has reported is a strong lead. |
| 122 | +3. **`wipe.hidden`.** A large number here explains an empty page with no bug |
| 123 | + attached. |
| 124 | +4. **`views`.** Zero on one page with sessions in the library narrows it to that |
| 125 | + page's resolver rather than the parser. |
| 126 | +5. **`data.communityDump`.** Missing names for new ships or items usually means |
| 127 | + the dump predates their patch, which the dataset now reports itself. |
| 128 | + |
| 129 | +`install.backups` at zero with `install.found` true means the app is reading a |
| 130 | +live `Game.log` and nothing else — a fresh install, or a channel with its |
| 131 | +backups cleared. That install cannot show history yet, and no amount of parser |
| 132 | +work will change it. |
0 commit comments