NWNX4 - resurrected

I am glad to announce the NWNX4 project development has resumed, with new maintainers !

Currently only @scottmunday84 and me are working on NWNX4, but we would be happy to welcome new contributors !

You can contribute in a number of ways:

  • Open issues on GitHub, detailing bugs you encounters or asking for new features. We would love to get some feedback on the existing issues.
  • Improve the wiki pages to document how NWNX4 and its plugins works. Currently the wiki is almost empty.
  • Improve the NWScript files to provide new features or better documentation related to NWNX4 plugins.
  • Submit pull requests on GitHub to provide new features, plugins or fix bugs (require C++ knowledge). Don’t worry if your are not very experienced in C++, your PRs will be reviewed and you will receive help :wink:

Expect new features, plugins and improvements to come very soon :slightly_smiling_face:

Links

1 Like

Version v0.1.0 (first resurrected release)

This NWNX4 release brings the same features and interfaces as the official (now abandoned) version from nwnx4.org, and should be a drop-in replacement.

Under the hood, a lot of work has been done to update the codebase to be easily built with modern compilers and libraries, and CI pipelines have been setup to help newcomers submit pull requests.

On the plugin-side, this release comes with a lot more plugins than the official one:

  • xp_bugfix
  • xp_fastboot
  • xp_funcs *
  • xp_mysql and xp_sqlite
  • xp_objectattributes *
  • xp_pickpocket *
  • xp_profiler *
  • xp_srvadmin
  • xp_time

Some of these plugins (those marked with a *) may not be on-par with versions posted on the vault (maybe older, maybe newer). Please open an issue here if you find any difference.

Currently, only the MySQL plugin has gained new features:

  • Fixed the SQL object storage (The abandoned nwnx4 release had broken SCORCO functions).
  • Now uses the latest MariaDB client connector. This allows the plugin to connect to the SQL server using more secure authentication methods.
  • Added a charset option to correctly set the charset on connection (and re-connections), instead of sending SET NAMES utf8 queries.

Huge thanks to @SkywingvL and @scottmunday84 for helping me and supporting me to resurrect this important project ! - Crom

Version v0.2.0

NWNX changes

  • Fixed the gamespy watchdog not receiving ping responses on some configurations
  • Fixed the restart command not being executed correctly

Plugin changes

New plugin: xp_rpc !

xp_rpc is a plugin that allows high performance RPC communication between an NWN2 server and any set of microservices. A microservice can be built in any supported language of both gRPC and Protocol Buffers.
See the wiki for more information !

xp_bugfix

  • Fix a bug where the server crashed when BootPC cas called twice on the same PC
  • Fix a server crash when a character with more than 255 spells connects to the server
  • Fix a server crash when a player initiates a rest while in transition between two areas

xp_mysql / xp_sqlite

  • Added the function SQLGetLastInsertedID() to return the ID of the last inserted row

Huge thanks to all contributors ! :tada:

can x4 be hooked into single-player games? if not, any plans to make it so?

either way, good job :)

Currently there it’s not very practical to ship nwnx4 with custom modules, but it’s definitely something we want to do !

There are two issues that needs to be addressed in order to be able for players to unpack an archive and start nwnx4:

2 Likes

thanks for the info so far,

i would (hopefully will) look into it more, to ask better questions. Am not sure what the relation is between Nwn2 and NwNx4 …

Can it be considered a frontend for the nwn2 executable ?

It’s more a launcher for nwn2server.exe (not the game client nwn2main.exe).

NWNX4 starts the nwn2server process and inject a DLL (some custom code) into the nwn2server process, in order to apply some patches to the nwn2server executable during startup.
These patches are provided by NWNX4 plugins and do a lot of different things, like fixing game bugs, performance and stability (xp_bugfix), give access to SQL databases (xp_sqlite, xp_mysql), allow the modification of character files (xp_objectattributes), …

It’s probably not well known by solo module developers, but I bet all PW servers out there are already using NWNX4 (at least the old version)

1 Like

sounds like it shouldn’t be too difficult to adapt it to start nwn2main.exe

But then there’s a bit of a conflict with the ClientExtension …

and, am guessing it’d require some proficiency with a disassember to get at game-code that one might want to alter the behavior of … ?

 
eg. Currently the game doesn’t respect “auto-fail on a roll of 1” for two of the 3 savetypes … /iirc

The DLL injection and patching rely on some static addresses in memory, and I would expect those addresses to be very different for nwn2main.exe.

The two are complementary. The ClientExtension improves player experience with nwn2main.exe and NWNX4 extends the capabilities and stability of nwn2server.

Yes, and to be honest this is beyond my skills… some smart people already found some useful pointers and created plugins with them. I only updated their code to build on modern compilers.

1 Like

ah… yeh :\

ok

i see. A guy could learn it but it’d take a while to get the skillz up.

 
 
Thanks Crom, my understanding of X4 leveled up ;)

Version v1.0.0

/!\ Breaking changes

New file tree

The location of plugin files have been modified in order to ease the process of upgrading nwnx4 and its plugins.

tl;dr: Move all your xp_*.dll files into the plugins/ folder before upgrading nwnx4, and you should be fine for this part.

Here’s how the new file tree works:

  • config.example\: Contains config templates for nwnx4 and its official plugins. On first installation, you must copy those config files into the root nwnx4 directory. Files under config.example\ will be updated with nwnx4, and you will need to compare them with your copies in order to support new features when nwnx4 will be updated in the future.
  • nwn2server-dll\: Contains all DLL files that the NWN2Server process will need (you don’t need to copy them into the nwn2 installation dir anymore). This directory is automatically added to the DLL search path for the NWN2Server process, so you can add your own DLL files to it this folder. Note that this folder is not searched by the .NET runtime, so it will not work with xp_AuroraServerNWScript DLLs.
  • nwscript\: Contains the include scripts to copy to your module (nothing changed here).
  • plugins\: Contains all nwnx4 plugin DLL files. By default, nwnx4 will search this directory when loading plugins (see “Plugins loading” below). In order to install additional plugins, you will need to copy their DLL files into this folder.

Note that .ini and .txt (logs) files are still stored in the nwnx4 root directory. This is on purpose, to be consistent with unofficial plugins that expect their config and log files to be located here. Only the plugin DLL files have been moved to a separate directory.

Plugins loading

The way plugins are loaded has been modified in order to explicitly chose which plugins must be loaded. This makes upgrading easier and prevents conflicts between some plugins like xp_mysql and xp_sqlite.

nwnx.ini now has the plugin_list option:

# List of all plugins to load when starting the NWN2Server process
# The list is comma-separated, and each element must be either:
# - A plugin name without the path extension. The associated DLL file must be
#   located inside the plugins/ folder of nwnx4.
# - A plugin full path like 'C:\Program File\plugins\xp_yourplugin.dll' or
#   'dev_plugins\xp_yourplugin.dll'.
#   Relative paths must be relative to the nwnx4 directory.
#
# default: load all plugins in the nwnx4 folder (legacy behavior, not recommended)
plugin_list = xp_bugfix, xp_sqlite, xp_funcs, xp_time, xp_srvadmin, xp_rpc, xp_objectattributes

By default if you don’t update your nwnx.ini file, nwnx will load all plugins inside the plugins/ folder. This is not recommended and will cause issues if you don’t manually remove plugins you don’t want to load, like xp_mysql / xp_sqlite.

New features

Packaging nwnx4 with your module

You can now assemble a package containing nwnx4 and your custom content and module(s), that players can quickly extract to start a NWN2 server and connect to it. The main idea is to enhance single-player experience by providing server-grade features, like game logic fixes, SQL storage, advanced scripting, …

See the “How to: Distribute nwnx4 with your module” section of README.md

The following features have been implemented for supporting packages:

xp_pickpocket

xp_pickpocket was crashing the server when somebody tried to pickpocket somebody. This is no longer the case thanks to @ap5d !

xp_sqlite

Now supports SCORCO functions (store and retrieve objects) !
While SQLite is slower and less reliable than MySQL, it is very practical for making nwnx4 + module packages because it does not require to install any additional software.

Huge thanks to all contributors ! :tada:

3 Likes

v1.0.1

This release fixes a bug where xp_ServerExts (not shipped with nwnx4) was unable to use some functions provided by xp_bugfix, causing error messages like Failed to resolve symbol SetPacketFilterCallouts. .

This bug affects all plugins that requires xp_bugfix to be installed (and now it is fixed).

2 Likes

v1.1.0

New CPlugin ABI

There is a new ABI for writing nwnx4 plugins, that should be much simpler to implement for languages other than C++.

The new ABI is defined here: nwnx4/nwnx_cplugin.h at main · nwn2dev/nwnx4 · GitHub

If you are writing a C or C++ plugin, you can directly include this file in your C / C++ project. Most compiled languages can generate C-compatible ABIs, so if your plugin is written in another language, you will need to “translate” this file for your language.

Currently there are two plugins that use the new CPlugin ABI:

nwnx_include.nss has been updated to provide additional functions for querying information about the new CPlugins.

Of course, the previous ABIs are still supported and older plugins will continue to be compatible with NWNX4.

Removed RPC

Unless you were using the xp_rpc plugin, these changes should not affect you.

  • Removed RPC logging facilities
    • RPC plugins could log message through the nwnx4 logging system to nwnx.txt. This is no longer the case.
    • RPC plugins must now implement their own logging system, just like any other nwnx4 plugin
  • Removed the xp_rpc plugin

Other changes

  • Updated dependencies
  • Added PDB files for debugging
  • Fixed a bug where the nwn2server would not launch if the parameters list was too long
  • xp_pickpocket: Fixed the NWScript function PickpocketContinue to reflect what it is supposed to do
  • xp_bugfix: version 1.0.73
  • xp_sqlite: enabled SCORCO functions hooking for object storage

Huge thanks to all contributors ! :tada:

4 Likes

v1.2.0

Separated user and install files & CPlugin GFF ABI

Separated config and install directories

NWNX4 now supports splitting files between two directories:

  • Install directory (e.g. C:\Program Files\NWNX4\)
    This directory contains all nwnx4 files from the nwnx4 release zip. Those files should not be modified by the user when configuring NWNX4 for their server. This is very similar to the NWN2 install directory.
  • User directory (e.g. Documents\NWNX4-myserver\)
    This directory contains all configuration files, custom plugins, log files, and other files created by nwnx4. This is very similar to the NWN2 home directory (that is located in Documents/Neverwinter Nights 2 by default).

This should help a lot for installing and updating nwnx4 while keeping track of files that have been added by the user.
A typical install would have a read-only NWNX4 install dir (placed by the admin or an installer inside Program Files), and a writable NWNX4 user dir placed in any handy location.
Multiple NWNX4 user dirs can share the same install dir. This is very practical if you need to run multiple nwn2 servers on the same machine.

When launching a nwnx4 executable (controller or gui), the current working directory is used as the user dir. The NWNX4_Controller has an additional parameter “-userdir” to set the user directory to something else. If the user directory is empty, it is populated with the example config files and useful sub-folders.

Here are two methods for launching NWNX4_Gui with a specific user directory:

  1. Create a shortcut to NWNX4_Gui.exe, edit its properties and change the “Start in” field to set the path to your user directory.
  2. Create a .bat file to launch “NWNX4_Gui.exe”, containing:
    REM Moving to the user directory
    cd %USERPROFILE%\Documents\NWNX4-myserver
    REM Starting NWNX4
    "C:\Program Files (x86)\nwnx4\NWNX4_Gui.exe"
    

Compatibility notes

Launching a nwnx4 executable with a shortcut or by double clicking the exe file, will set the user directory to be the same as the install directory, and everything will behave exactly like previous NWNX4 versions (the user and install directories are merged together).

Plugins only receives the nwnx4 user dir path when loaded (except for CPlugins), meaning they cannot reach files that are located in the nwnx4 install dir. This might cause some issues for some plugins, but I am not aware of any of such plugin.
However, if you encounter this issue, you can solve it by either copying the required files from the install dir into the user dir, or going back to the merged user+install dir setup.

If a plugin is present in both the install dir and user dir, the plugin from the user dir will be loaded. This can be useful if you need a custom xp_mysql plugin that is different from the official.

CPlugin ABI changes

You can now send and receive GFF data between the NWN2 server and a NWNX4 plugin using the CPlugin ABI.

New endpoints

  • NWNXCPlugin_GetGFFSize: Called by RetrieveCampaignObject, immediately before NWNXCPlugin_GetGFF, to get the size of the buffer that needs to be allocated for receiving GFF data.
  • NWNXCPlugin_GetGFF: Called by RetrieveCampaignObject to copy GFF data into the allocated buffer. This GFF data is then parsed and “instantiated” in-game.
  • NWNXCPlugin_SetGFF: Called by StoreCampaignObject

NWNXCPlugin_InitInfo

  • Renamed nwnx_path to nwnx_user_path
  • Added nwnx_install_path
1 Like

v1.2.1

Fixes a crash when restarting the nwn2server process, when using NWNX4_Gui.exe

2 Likes

v1.2.2

Fixes CPlugin NWNX install / user paths pointing to freed memory. This only affected CPlugins.

2 Likes