Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,13 @@
*.out
*.app

Binaries/
Intermediates/
BuildFiles/
Output/
vsxmake2022/
Output/
build/
.xmake/
RE-UE4SS/
Mods/*
!xmake.lua
5 changes: 0 additions & 5 deletions .gitmodules

This file was deleted.

7 changes: 0 additions & 7 deletions CMakeLists.txt

This file was deleted.

1 change: 1 addition & 0 deletions Mods/xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
includes("*/xmake.lua")
1 change: 0 additions & 1 deletion MyCPPMods/CMakeLists.txt

This file was deleted.

9 changes: 0 additions & 9 deletions MyCPPMods/MyExampleMod/CMakeLists.txt

This file was deleted.

66 changes: 0 additions & 66 deletions MyCPPMods/MyExampleMod/src/dllmain.cpp

This file was deleted.

1 change: 0 additions & 1 deletion RE-UE4SS
Submodule RE-UE4SS deleted from ce074a
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,42 @@
# UE4SSCPPTemplate


This repository includes some custom `xmake` tasks to assist in your mod development.

- `xmake newmod`
- `xmake installmod`
- `xmake bi`
- `xmake ue4ss`

## `xmake newmod [-r, --regen] name`

The `newmod` command will ensure you have the UE4SS repository cloned and then bootstrap new mod creation.

Running `xmake newmod CoolMod` will generate `/Mods/CoolMod/...` in your repository and automatically link it with the xmake system. If you have VS2022 installed then the `newmod` command will also automatically generate a VS project which can be located at `/vsxmake2022/UE4SSCppTemplate.sln`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .sln inside vsxmake2022 is called UE4SS-<my mod name>.sln


## `xmake installmod [-d, --exedir] name`

The `installmod` command will copy your build output to a specific game directory. The configuration of the build you want to install is derived from the currently configured xmake mode (`xmake f -m <mode>`). This configured mode is global to the `RE-UE4SS` repo and all the mods in the `Mods` folder. If you want to specify a specific configuration to install, then you can change the xmake configuration by running `xmake f -m "Game__Debug__Win64"`.

Running `xmake installmod --exedir="Path\To\Your\Game\Dir" CoolMod` will copy the build output and install `CoolMod` in the correct subdir in the game's mod folder.

Note that running `xmake installmod` does not automatically build your mod. You have to manually build it with `xmake build` or use the `xmake bi` task to build and install your mod.

## `xmake bi [-d, --exedir] name`

This is a shorthand task that will run `xmake build -y <modname>` followed by the `xmake installmod` command. This one-liner command facilitates rapid testing/iterating of your mod.

## `xmake ue4ss [-r, --remote] [-u, --update]`

By default, the `xmake newmod` command will attempt to checkout the latest release tag of UE4SS to build your mods against. If you want to build your mods against a different remote then you can specify a branch or tag as the `--remote=` parameter.

`xmake ue4ss --remote="v3.1.0"` will attempt to use tag "v3.1.0" as the checked out UE4SS version.

You can use the latest release tag by specifying `xmake ue4ss --remote="latest"`.

You can also specify branches instead of tags to use. `xmake ue4ss --remote=main` will checkout the `main` branch of UE4SS.

If you want to get upstream changes from remote branches then you can use the `--update` arg to pull remote changes.

`xmake ue4ss --remote=main --update` will pull the latest remote changes from the `main` branch locally.

You can also run `xmake ue4ss --update` and xmake will try to pull changes from whatever branch your local UE4SS is currently on.
7 changes: 7 additions & 0 deletions Scripts/build_and_install.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import("core.base.option")
import("core.base.task")

function main()
task.run("build", {yes={}}, option.get("name"))
task.run("installmod", {exedir=option.get("exedir"), name=option.get("name")})
end
49 changes: 49 additions & 0 deletions Scripts/install_mod.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import("core.base.option")
import("core.base.task")
import("core.project.config")
import("core.project.project")

function main()
-- validate?
local mod_name = option.get("name")
local mod_dir = path.join(option.get("exedir"), "Mods", mod_name)

-- Get the current build mode. ex: Game__Shipping__Win64
config.load()
local mode = config.get("mode")
print("Using the mode from xmake config: %s", mode)

-- Load the dll location from the xmake target for the mod.
local target = project.target(mod_name)

if not target then
print("Target %s not found.", mod_name)
os.exit()
end

-- Step 1: Check if we have build output.
if not os.exists(target:targetfile()) then
print("Build output not detected at %s", target:targetfile())
os.exit()
end

-- Step 2: Copy to the mods folder.
local dll_dir = path.join(mod_dir, "dlls")
if not os.exists(dll_dir) then
print("%s not found. Creating...", dll_dir)
os.mkdir(dll_dir)
end

os.cp(target:targetfile(), path.join(dll_dir, "main.dll"))

if os.exists(target:symbolfile()) then
print("Symbol file detected. Copying to mod directory...")
os.cp(target:symbolfile(), path.join(dll_dir, "main.pdb"))
end

-- Step 3: Create the enabled.txt in the mods folder.
if not os.exists(path.join(mod_dir, "enabled.txt")) then
print("enabled.txt not found. Creating...")
io.writefile(path.join(mod_dir, "enabled.txt"))
end
end
63 changes: 63 additions & 0 deletions Scripts/new_mod.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import("core.base.option")
import("devel.git")
import("devel.git.submodule")
import("core.base.task")
import("detect.sdks.find_vstudio")
import("core.base.task")
import("core.base.semver")

function main()

-- validate?
local mod_name = option.get("name")

if not mod_name then
print("Please specify a mod name.")
os.exit()
end

-- Step 1: Initialise or update RE-UE4SS repository on the latest release tag.
if not os.exists(path.join("$(projectdir)", "RE-UE4SS")) then
print("UE4SS repository not yet cloned. Automatically cloning...")
task.run("ue4ss", {update={}, remote="latest"})
end

-- Step 2: Create mod directory and files.
local mods_dir = path.join("$(projectdir)", "Mods")

if os.exists(mod_name) then
if option.get("regen") then
print("Regenerating mod directory and files.")
CreateModFiles(mod_name, mods_dir)
else
print("Mod directory already exists. Run with the --regen flag to regenerate mod files.")
os.exit()
end
else
CreateModFiles(mod_name, mods_dir)
end

-- Step 3: Generate VS project if VS2022 is installed
local vs_versions = find_vstudio()
if(vs_versions and vs_versions["2022"]) then
-- Equivalent to xmake project -k vsxmake2022 -y
task.run("project", {kind="vsxmake2022", yes={}})
end
end

function CreateModFiles(mod_name, mods_dir)
print("Creating mod directory and files...")
local mod_dir = path.join(mods_dir, mod_name)
os.mkdir(mod_dir)

local mod_xmake = path.join(mod_dir, "xmake.lua")
os.cp(path.join("$(projectdir)", "xmake_template.lua"), mod_xmake)

io.replace(mod_xmake, "MyAwesomeMod", mod_name)

local mod_cpp = path.join(mod_dir, "dllmain.cpp")
os.cp(path.join("$(projectdir)", "dllmain_template.cpp"), mod_cpp)
io.replace(mod_cpp, "MyAwesomeMod", mod_name)
io.replace(mod_cpp, "MY_AWESOME_MOD_API", string.upper(mod_name).."_API")
end

78 changes: 78 additions & 0 deletions Scripts/ue4ss_git.lua
Comment thread
bitonality marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import("core.base.option")
import("devel.git")
import("devel.git.submodule")
import("core.base.semver")

local ue4ss_url = "https://github.com/UE4SS-RE/RE-UE4SS.git"
local ue4ss_dir = "RE-UE4SS"

function main()
local remote = option.get("remote")
local update = option.get("update")

if (remote == nil and update == nil) then
print("No arguments. Run 'xmake ue4ss --help'")
os.exit()
end

local ue4ss_repo = path.join("$(projectdir)", ue4ss_dir)
if not os.exists(ue4ss_repo) then
print("Cloning UE4SS Repository...")
git.clone(ue4ss_url)
end

if remote then
-- Special handling if the user wants to find the 'latest' release tag.
if remote == "latest" then
print("Attempting to find latest release tag...")
local tags = git.tags(ue4ss_url)
local latest_tag
for _,tag in ipairs(tags) do
if semver.is_valid(tag) then
if not latest_tag then
latest_tag = tag
end

if semver.compare(tag, latest_tag) == 1 then
latest_tag = tag
end
end
end
remote = latest_tag
end

-- Returns a matching version/tag/branch based on the provided "remote" string.
-- Uses semantic versioning or branch naming.
local remote, type = semver.select(remote, nil, git.tags(ue4ss_url), git.branches(ue4ss_url))
if not remote then
print("%s was not found as a valid git remote.")
os.exit()
end

if type == "tag" then
-- Special logic to ensure we don't check out a tag that doesn't have xmake.
-- This would put the user's local repo into an unrecoverable state.
if not semver.satisfies(remote, ">3.0.1") then
print("The latest tag %s is not compatible with xmake. Using 'main' branch instead of a tag.", remote)
remote = "main"
type = "branch"
end
end

print("Checking out %s %s...", type, remote)
git.checkout(remote,{repodir=ue4ss_dir})
end

if update then
-- If the user specifies a tag, then we don't need to pull/update.
local cur_branch = git.branch({repodir = ue4ss_dir})
if cur_branch then
git.pull({remote = "origin", tags = true, repodir = ue4ss_dir})
else
print("UE4SS is not currently a branch. No remote changes to pull.")
end

print("Updating submodule")
submodule.update({repodir = ue4ss_dir, recursive = true, init=true})
end
end
Loading