v0.1.0
This was the first publicly acknowledged release of tera-proxy. Before then, most things had been kept under the radar, but with things suddenly getting noticed, it was time to start getting serious.
Below is a copy of a page from the tera-proxy wiki titled “Upgrading to 1.0.0”. Let’s pretend it wasn’t actually 1.0.0 because I keep adding breaking changes and I don’t want to bump to v2 already. Dear semver, I’m sorry. Let’s start with a clean slate and call it “0.1.0”.
Both tera-data and tera-proxy-game have undergone a number of potentially breaking changes. Commit logs for each can be seen here:
- tera-proxy-game
- tera-data, which had the parser split into tera-data-parser-js
For normal users this will mean completely updating tera-proxy-game and tera-data as well as installing tera-data-parser. It is probably most convenient to just get a new copy of the whole thing and transferring old proxy modules over. One will be provided once Valkyrie lands on NA.
For module developers, most things will be backwards compatible except for two specific cases:
- implicit
rawhooks on*(see: logger) - explicit
prehooks. I don’t think anyone ever used these but the oldtypeparameter inDispatch#hook()is now aversionparameter.
Details are below.
tera-data(-parser-js)
Separation of Code and Data
tera-data now only houses mappings and protocol definitions. The Node.js parser was moved to meishuu/tera-data-parser-js which will be renamed tera-data-parser when installed via npm.
Both tera-data-parser-js and tera-proxy-game have a peer dependency on tera-data, so you must install all three together for things to work nicely.
Original Identifiers
Before, tera-data converted names to use lowerCamelCase. This has been dropped in favor of using the original names. For module developers, this is backwards compatible as tera-proxy-game’s Dispatch performs transformations to ensure the old style still works. However, the methods exposed by tera-data-parser-js’s Protocol do not perform those transformations.
Versioning
All definitions now include a version number before the .def extension. Instead of changing existing versions of a definition, contributors must instead commit the updated definition as a new file with the version number incremented. For more information, check the updated README.
Extras
-
Tests, linting, and CI/coverage tools have been added to the parser. Tests are still being written, but eventually this should mean no more silly regressions. It is strongly recommended to install with
NODE_ENV=productionor--only=productionif you don’t need these, which you probably don’t. -
Protocolis now implemented as a class, and the exportedprotocolis an instance of it. You can create another instance by callingprotocol.createInstance([args...]). This will be handy for anyone needing to support multiple protocol versions. -
Protocolnow lazy loads data files, which means themapandmessagesmaps may be empty if they are accessed before any call toload,parse,write, (orresolveIdentifier). By default, it will load fromrequire.resolve('tera-data')and this is likely what you’ll want to pass toload()as well. -
All types (including int64s) now have default values for writing (0, or empty array, or empty string).
-
Anything using the exported
sysmsgmust perform its own conversions because these were updated to the new name case system. Also it’s very ugly and untested and will probably catch up toprotocoleventually, but not now.
tera-proxy-game
Versioning
See above. With the advent of versioning, Dispatch#hook() as well as the toClient() and toServer() methods now expect the second parameter to be the version number. If it is not a numeric value, it may be '*' to use the latest version (not recommended) or 'raw' to use a raw hook which performs no parsing. If no version info is supplied, it will emit warnings to the console unless the environment variable NO_WARN_IMPLIED_VERSION is nonempty.
Currently not implemented but hopefully very soon will be deprecation warnings if the requested version is not the latest. You will likely also be able to disable the warnings through an environment variable.
Hook Options
The parameters for Dispatch#hook() are now identifier[, version][, options], callback. options is an object with the following optional properties:
-
order: A lower number causes this hook to run before hooks with a higherorder. This defaults to 0, so you can imagine negative values running closer to the source side and positive values running closer to the destination side. This is helpful for modules that way want to examine packets before another module modifies or silences them, or filter to what the receiving side will see by running later than most other hooks. -
type: One of'real'(default),'fake', or'all'. Packets created and sent throughDispatchare now first routed back through the handler, so now you can, for instance, examine only “fake” (generated) packets by making a hook withtype: 'fake'. Just be extra sure that any packets generated in afake/allhook do not generate more in an infinite loop.
These are pretty untested right now so don’t expect these options to be perfect, but they’re there for anyone who might need them.
Extras
-
All hook callbacks are now passed an extra parameter at the end,
fake, to identify if the packet was generated by the proxy. -
Before,
Dispatchwould dump a full stacktrace upon encountering a warning or error. This was pretty unwieldy to look at, so now it trims native node callsites as well astera-proxy-gamecallsites unless deemed necessary. -
Dispatch#unhook()is currently untested, but before it accepted a callback. Now, it expects the hook object returned from callingDispatch#hook(). -
Dispatch#handle()used to take the opcode as the first argument. This was redundant because it was always being retrieved from the second argument (the data buffer) anyway, so it was removed and the new parameter list isdata, fromServer[, fake]. -
There were a number of changes to how things were being implemented. Thus, performance may have changed. At the end of the day, there probably isn’t nearly enough processing at all for any extra overhead to matter, but it’s worth pointing out just in case of the off chance that there’s something really inefficient about what we’re doing now.