Skip to content

Commit

Permalink
Merge pull request #300 from OutpostUniverse/FinalizeRelease3.0.0
Browse files Browse the repository at this point in the history
Finalize release3.0.0
  • Loading branch information
Brett208 authored Jun 13, 2020
2 parents b12309d + 2d60e3b commit 4a8fea2
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 47 deletions.
127 changes: 89 additions & 38 deletions ReadMe.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Outpost 2 Extension Module Loader
------------------------------------------

Outpost 2 extension module loader (op2ext) allows modifying and extending Outpost 2 through loading of alternate game resources or injecting independently compiled C/C++ DLLs. The current version of Outpost 2 is maintained by the Outpost 2 community and may be found at https://www.outpost2.net/.
Outpost 2 extension module loader (op2ext) allows modifying and extending Outpost 2 through loading of alternate game resources or injecting independently compiled DLLs. Read more about Outpost 2 and the Outpost Universe Community at https://www.outpost2.net/.

Authors: BlackBox (op2hacker)
Hooman
Expand All @@ -11,51 +11,55 @@ Authors: BlackBox (op2hacker)
Summary
------------------------------------------

Outpost 2 Extension is a dynamic link library (DLL) written in C++. Source code may be found at https://github.com/OutpostUniverse/op2ext. The op2ext library compiles for x86 Windows. The current solution/project files use Visual Studio.
Outpost 2 Extension is a dynamic link library (DLL) written in C++. Source code may be found at https://github.com/OutpostUniverse/op2ext. The op2ext library targets x86 Windows and can be compiled using Visual Studio on Windows or mingw on Linux. Visual Studio and make project files are provided. A C++17 compliant compiler is required.

Outpost 2 requires loading libraries to fixed base addresses. Modern compilers default to randomized base addresses. To prevent possible interference with other libraries associated with Outpost 2, op2ext is designed to load into address 0x10000000.

Both the op2ext and TestModule projects use post build event scripts to copy files into the Outpost 2 directory. The default expected location is ./Outpost2/. If you plan on testing op2ext against a copy of Outpost 2 in a different directory, review and adjust the post build scripts before compiling.
The Visual Studio project files for op2ext and the Test Module contain a post build event to automatically copy compiled artifacts to an Outpost 2 directory for testing. To take advantage of this feature, set an environment Variable named 'Outpost2Path' that is the location of the test copy of Outpost 2.

op2ext provides the following extensions for Outpost 2:

* Override default vol files and loading new vol files by placing them in the folder ./Addons.
* Dynamically load new vol files placed in the root directory of Outpost 2.

- Also supports dynamically loading new vol files placed in the root directory of Outpost 2.
* Override default vol files and load new vol files by placing them in the folder ./Addons.

* Add a single module to Outpost 2 using the command line argument /loadmod
* Built In Modules

- Allows adding modules to Outpost 2 that are compiled within op2ext's dll.
- Built in modules can be toggled on or off using the .ini file.

* External Modules

- May be loaded via the command line using the /loadmod command.
- May be loaded by instructions contained within the Outpost2 ini file.
- Override default game resource files, to include vol files, clm (music) file, in game videos, etc.
- Modify and extend the behavior of Outpost 2 by exposing a new C/C++ DLL before game is initialized.
- Designed for modules the user wants to include in Outpost 2 sometimes, but not on a permanent basis.

* Add multiple modules using the Outpost2.ini file

- Modify and extend the behavior of Outpost 2 by exposing multiple modules specified in the Outpost2.ini file.
- Allows getting and setting properties for modules in the Outpost2.ini file.
- Designed for modules the user wants to include in Outpost 2 on a permanent or semi-permanent basis.

* IP dropdown box for net play
- Modify and extend the behavior of Outpost 2 by hooking custom DLLs before game is initialized.
- Ini modules may use Outpost2.ini to set and retrieve persiting properties.

- Allows saving previously used IP address in a drop-down menu for easy selection when joining repeat matches.

* Unified message logging

Writing Custom Modules
------------------------------------------
op2ext.dll is included in releases of Outpost 2 on Outpost Universe. This DLL allow integration of separately compiled modules into any copy of Outpost 2. Custom modules must be designed to hook into op2ext.dll through functions that export using the C Application Binary Interface (ABI). Modules may also consist of simply overwriting game assets without additional programming.
Modules may be written either within op2ext as built in modules or separately as external modules. External modules may be specified for loading either on the command line or through the .ini file.

Each new module for Outpost 2 should be placed in a separate directory that resides in the root directory of Outpost 2. The module should be designed to interface with Outpost 2 by either being added as an argument to the command line when opening Outpost 2 or by being specified in the Outpost2.ini file.
External modules can hook into op2ext.dll through functions that export using the C Application Binary Interface (ABI). If desired, external modules may simply overwriting game assets without additional programming.

The two types of modules, console and .ini modules, use different function hooks to pass data into op2ext. They both have access to the same set of op2ext exported functions. To gain access to op2ext's exported functions, include op2ext.h in your project. Detailed usage instructions for the functions are contained in op2ext.h.
To gain access to op2ext's exported functions, include op2ext.h in your project. Detailed usage instructions for the functions are contained in op2ext.h.

Custom modules are encouraged to use the Log function to log useful information for troubleshooting various failures or degraded states. op2ext itself uses the logger as well. The log file will be named Outpost2Log.txt and will be created in the same directory as Outpost2.exe.
Each external module for Outpost 2 should be placed in a separate directory that resides in the root directory of Outpost 2. Module names are case insensitive. You can check if a module is loaded using functions declared in op2ext.h.

Module names are case insensitive. You can check if a module is loaded using functions declared in op2ext.h.
Custom modules are encouraged to use the Log functions to log useful information for troubleshooting various failures or degraded states. op2ext itself uses the logger internally. The log file is named Outpost2Log.txt and will be created in the same directory as Outpost2.exe.

Console Modules
------------------------------------------
If the module needs to redirect where Outpost 2 looks for standard game resources without using a custom DLL and/or should not always be included with Outpost 2, consider making it a console module.
Available functions for use by external modules to hook into Outpost 2 are below. Previously, Console and ini modules used different functions, but both function sets are now interchangeable.

- InitMod(char* sectionName) or mod_init()
- RunMod() or mod_run()
- DestroyMod() or mod_destroy()

See the .ini module and console module sample for detailed use instructions.

External modules will automatically search their root directory for game resources and add them to Outpost 2. This allows adding or overwriting standard game resources without adding a DLL.

Game resources that may be redirected using a console module (Due to setting the ART_PATH property within Outpost 2):

Expand All @@ -64,29 +68,30 @@ Game resources that may be redirected using a console module (Due to setting the
- music1.wav (title music track)
- All in game video files

Available functions for a console module to export to op2ext.dll are below. See the console module sample for detailed use instructions.

- mod_init()
- mod_run()
- mod_destroy()
Console Module Specifics
------------------------------------------

To load a custom module with Outpost 2:
To load a console module with Outpost 2:

1. Create a new directory in the root directory of Outpost 2. Name the directory after the module.
2. Add the appropriate files and DLL if desired to the directory. The dll must be named op2mod.dll.
2. Add the appropriate resource files to the directory. Add custom DLL if desired. To call as a console module, the dll must be named op2mod.dll.
3. Call 'Outpost2.exe /loadmod directoryName' when executing Outpost 2. For example, Outpost2.exe /loadmod multitek2.
4. Consider creating a .bat (batch) file that allows for loading the module without opening the command prompt.

To load multiple modules, simply add more arguments after /loadmod. For example /loadmod multitek2 ColorMod1 CustomMod

To avoid undefined behaviour, console modules should only be stored as a child of Outpost 2's root directory (not further nested or outside of the game's root directory). When calling /loadmod, no trailing or prefixed directory separator should be used. IE do not call `/loadmod testmodule\` or `/loadmod .\testmodule`. A proper call would be '/loadmod testmodule'.

.ini Modules
.ini Module Specifics
------------------------------------------
If the module contains configurable settings, history, or other data, and it is designed to be loaded through the Outpost2.ini file, consider making it a .ini module. The file Outpost2.ini follows standard Windows .ini file conventions and may be loaded and edited using standard Windows.h library functions.
The file Outpost2.ini follows standard Windows .ini file conventions. ini settings may be loaded and edited using standard Windows.h library functions.

Available functions for a .ini module to export to op2ext.dll are below. See the .ini module sample for detailed use instructions.
To load an ini module:

- InitMod(char* sectionName)
- DestroyMod()
1. Create a new directory in the root directory of Outpost 2. Name the directory after the module.
2. Add the appropriate resource files to the directory. Add custom DLL if desired.
3. Add the module name to Outpost2.ini under the ExternalModules section.
4. If storing or retrieving settings for the module in the Outpost2.ini file, create a new section in the .ini file for the module.


Module Serial Numbers
Expand All @@ -106,7 +111,7 @@ Vol files are a custom Outpost 2 storage format used to store in game files like

Vol files must be loaded into Outpost 2 before the game initializes. A module should accomplish this by adding vol files to Outpost 2 within the function mod_init/InitMod by calling AddVolToList. Alternatively, the addon directory or simply placing vol files in the Console Module's directory will load them automatically.

Outpost 2 only supports 31 vol files. If loading more than 31 vol files is requested, op2ext will not load any vol file past 31 and will warn the user on which vol files were not loaded. Outpost 2 will continue to load, but depending on what data was contained in the discarded vol file(s), the program may or may not be able to function normally.
op2ext lifts Outpost 2's restriction on only loading 31 vol files. In theory an unlimited number of vols could be added, but would likely be limited by the operating system's ability to open independent files.

Order of vol file precedence is below:

Expand All @@ -120,6 +125,48 @@ Order of vol file precedence is below:
Change Log
------------------------------------------

Version 3.0.0

* Remove public functions IsConsoleModuleLoaded & IsIniModuleLoaded
- A breaking change from version 2.2.0
* Allow loading multiple console modules
* Allow GetConsoleModDir_s to also return the directory of an ini module
* Allow Logging error and debug messages from modules
- LogError
- LogDebug
* Add function hook for "Run" in ini modules
- Matches corresponding Run function hook in console modules
* Add concept of Built in Modules within op2ext
- Repackage IPDropDown as a Built in Module
- Add Earthworker Proximity Tasking as a Built in Module
* Allow toggling modules on and off using the Outpost2.ini file
- NOTICE: The INI file must be updated to new format when switching to this version of op2ext
* Improve logging framework
* Full support of mingw for compiling on Linux for Windows/Wine
* Significant backend archicture improvements
- Unify console and ini module loading
- Improve memory patching techniques
- Improve support of ini files
- Improve coverage of unit tests and support gmock
- Use continuous integration results to autopopulate release builds

To update an ini file to be compatible with op2ext 3.0.0:

Remove the LoadAddons line from the Game section (it is now replaced by the ExternalModules section)
[Game]
LoadAddons = "NetFix, NetHelper"

Add the following sections to the ini file:

[BuiltInModules]
EarthworkerProximityTasking = yes
IPDropDown = yes

[ExternalModules]
NetFix = yes
NetHelper = yes


Version 2.2.0

This version forces quotation marks ("") when passing a path containing spaces with the /loadmod switch. Earlier implementations would auto-combine paths with spaces if no quotation marks used, but this implementation only allowed passing paths with a single space in a row. "One space" would work, but "two spaces" would fail.
Expand All @@ -135,18 +182,21 @@ This version forces quotation marks ("") when passing a path containing spaces w
* Allow selecting non-experimental filesystem include when C++17 is available
* Add limited mingw project support for Linux compilations


Version 2.1.0

* Add message logger usable by op2ext and external modules.
* Deprecate GetCurrentModDir due to improper memory management across DLL boundaries.
* Add external API function GetConsoleModDir_s to replace deprecated GetCurrentModDir.
* Mark argument volName from function AddVolToList argument as const. This allows passing const values into the function.
* Lift 31 volume load restriction. Outpost 2 will be able to load effectively a limitless number of volumes.


Version 2.0.1

* Fix bug in Console Mod Loader that separated the executable's path into multiple arguments if the path included a space.


Version 2.0.0

* Add ability to load vol files with any name into Outpost 2 from the root directory.
Expand All @@ -161,6 +211,7 @@ Version 2.0.0
* Write a TestModule that is included with the project.
* Introduce C++11/14 practices into code base.


Version 1.0.0

* Several releases of op2ext were made prior to 2.0.0 which are not currently documented.
9 changes: 3 additions & 6 deletions SampleModules/ConsoleModuleSample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// op2ext will call the following 3 functions to support setup, running and destruction of module. Each function is optional to implement.
// The functions must be exported from the module's dll as shown belore for op2ext to register them. See the ReadMe file for more details.

//#include "op2ext.h" // Provides access to op2ext's public functions.
#include "op2ext.h" // Optional include for access to op2ext's public functions.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

Expand All @@ -20,11 +20,8 @@ EXPORT void mod_init()

EXPORT void mod_run()
{
// This code is called immediately after OP2Shell.dll is loaded and the language data is localized.
// (Right before the OP2 menu displays)
// It is too late to add VOLs or set the serial number (the game has already initialized this stuff)
// Use it to setup things that aren't already setup in mod_init. (The ResManager will be inited as well
// as the language strings)
// This function is called after OP2Shell.dll but before the OP2 menu displays.
// The ResManager will be initialized. New VOLs cannot be added and the game serial number cannot be updated.
}

EXPORT void mod_destroy()
Expand Down
14 changes: 11 additions & 3 deletions SampleModules/IniModuleSample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
// Additions to Outpost2.ini file
/*
. . .
LoadAddons = ". . . other modules . . ., ModuleSectionName"
[ExternalModules]
ModuleName = yes
. . .
[ModuleSectionName]
Expand All @@ -16,13 +17,13 @@ Dll = "ModuleSectionName\ModuleDllName.dll"
*/


//#include "op2ext.h" // Provides access to op2ext's public functions.
#include "op2ext.h" // Optional include for access to op2ext's public functions.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define EXPORT extern "C" __declspec(dllexport)

EXPORT void InitMod(char* iniSectionName) {
EXPORT void InitMod(char* iniSectionName)
{
// This code will be called during the DLL_PROCESS_ATTACH event of DllMain in op2ext.dll.
// No other code will have been run before this time.
Expand All @@ -34,10 +35,17 @@ EXPORT void InitMod(char* iniSectionName) {
// Call Windows function family WritePrivateProfileXXX to write settings to the .ini file.
}

EXPORT void RunMod()
{
// This function is called after OP2Shell.dll but before the OP2 menu displays.
// The ResManager will be initialized. New VOLs cannot be added and the game serial number cannot be updated.
}

EXPORT bool DestroyMod()
{
// This is called in the DLL_PROCESS_DETACH event of DllMain as op2ext.dll is unloading.
// Use it to cleanup any loose ends you created earlier in mod_init or mod_run.

// Return true/false based on success of module asset destruction.
return true;
}
Binary file modified srcDLL/op2ext.rc
Binary file not shown.
2 changes: 2 additions & 0 deletions testDll/op2ext.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "../SampleModules/ConsoleModuleSample.cpp"
#include "../SampleModules/IniModuleSample.cpp"

#ifdef __MINGW32__
#define DISABLE_DEPRECATED_WARNING \
Expand Down

0 comments on commit 4a8fea2

Please sign in to comment.