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
179 changes: 179 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
name: Build release packages

# Owner-only. workflow_dispatch already requires repo write access, and the
# job-level `if` below additionally restricts execution to the repository
# owner, so only the owner can produce a release.
on:
workflow_dispatch:
inputs:
version:
description: 'Release version / tag (e.g. v3.0)'
required: true
type: string
prerelease:
description: 'Mark the GitHub Release as a pre-release'
required: false
type: boolean
default: false

permissions:
contents: write

concurrency:
group: release-${{ inputs.version }}
cancel-in-progress: false

jobs:
release:
name: Compile plugins and package ${{ inputs.version }}
runs-on: ubuntu-latest
# Hard gate: only the repository owner may run this workflow.
if: github.actor == github.repository_owner

steps:
- uses: actions/checkout@v5

# Same upstream compiler our check_plugins.yml CI gates on — pinned to
# SourceMod 1.12. Putting `spcomp` on PATH for the next step.
- name: Setup SourcePawn Compiler (SourceMod 1.12)
uses: rumblefrog/setup-sp@master
with:
version: "1.12"

- name: Compile every shipped plugin from source
run: |
set -euo pipefail
SCRIPTING="$GITHUB_WORKSPACE/addons/sourcemod/scripting"
PLUGINS="$GITHUB_WORKSPACE/addons/sourcemod/plugins"

# Compile with the upstream SourceMod 1.12 compiler from
# rumblefrog/setup-sp (on PATH), NOT the spcomp binary committed in
# the repo — a known, reproducible toolchain. The -i include paths
# below still point at the repo's own sources/includes.
COMPILER="spcomp"

BUILD="$(mktemp -d)"
declare -A BUILT
FAILED=""
COUNT=0

# Drive off the .smx files that ship in the repo: each one is
# rebuilt from its same-named .sp source and written straight back
# to its original path (root / fixes / optional / disabled / etc.).
while IFS= read -r -d '' smx; do
name="$(basename "$smx" .smx)"

if [ -z "${BUILT[$name]:-}" ]; then
if [ -f "$SCRIPTING/$name.sp" ]; then
base="$SCRIPTING"
inc="$SCRIPTING/include"
elif [ -f "$SCRIPTING/sourcemod/$name.sp" ]; then
# Stock SourceMod plugins live one level down with their
# own include tree.
base="$SCRIPTING/sourcemod"
inc="$SCRIPTING/sourcemod/include"
else
echo "::error::No .sp source found for shipped plugin '$name' ($smx)"
FAILED="$FAILED $name"
continue
fi

echo "Compiling $name ..."
# Run with cwd = the scripting dir and a bare source filename,
# exactly like check_plugins.yml: some plugins (e.g. readyup)
# use working-directory-relative quoted #includes that only
# resolve from there. -i / -o / $BUILD are absolute, so the
# subshell cd does not affect them.
if ( cd "$base" && "$COMPILER" -E -w234 -w217 -O2 -v2 -i "$inc" "-o$BUILD/$name.smx" "$name.sp" ); then
BUILT[$name]="$BUILD/$name.smx"
else
echo "::error::Failed to compile '$name' ($base/$name.sp)"
FAILED="$FAILED $name"
continue
fi
fi

cp -f "${BUILT[$name]}" "$smx"
COUNT=$((COUNT + 1))
done < <(find "$PLUGINS" -name '*.smx' -print0)

echo "Refreshed $COUNT plugin file(s) from ${#BUILT[@]} unique source(s)."
if [ -n "$FAILED" ]; then
echo "::error::One or more plugins failed to build:$FAILED"
exit 1
fi

- name: Stage the drop-in overlay
run: |
set -euo pipefail
STAGE="$GITHUB_WORKSPACE/.release"
rm -rf "$STAGE"
mkdir -p "$STAGE"

# Lean runtime overlay: only what gets dropped over left4dead2/.
cp -a \
addons cfg scripts \
host.txt motd.txt myhost.txt mymotd.txt \
README.md LICENSE \
"$STAGE"/

# Exclude the SourcePawn sources and the bundled compiler from the
# shipped overlay (the compiled .smx in plugins/ are what runs).
rm -rf "$STAGE/addons/sourcemod/scripting"

echo "STAGE=$STAGE" >> "$GITHUB_ENV"

- name: Build Linux archive (.so natives only)
run: |
set -euo pipefail
NAME="L4D2-Competitive-Rework-${{ inputs.version }}-linux"
OUT="$GITHUB_WORKSPACE/$NAME.tar.gz"
# Drop every Windows native; keep the .so files.
tar -czf "$OUT" --exclude='*.dll' -C "$STAGE" .
echo "LINUX_ASSET=$OUT" >> "$GITHUB_ENV"

- name: Build Windows archive (.dll natives only)
run: |
set -euo pipefail
NAME="L4D2-Competitive-Rework-${{ inputs.version }}-windows"
OUT="$GITHUB_WORKSPACE/$NAME.zip"
# Drop every Linux native; keep the .dll files.
( cd "$STAGE" && zip -qr "$OUT" . -x '*.so' )
echo "WIN_ASSET=$OUT" >> "$GITHUB_ENV"

- name: Publish draft GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
VER="${{ inputs.version }}"
PRE=""
if [ "${{ inputs.prerelease }}" = "true" ]; then PRE="--prerelease"; fi

# Static platform preamble, built via printf so no YAML/shell
# indentation leaks in and gets rendered as a markdown code block.
# GitHub's auto-generated changelog (--generate-notes) is appended
# after this by gh release create.
NOTES="$RUNNER_TEMP/release-notes.md"
{
printf 'Automated build of `%s`.\n\n' "$VER"
printf -- '- **Linux** (`*-linux.tar.gz`): `.so` natives only.\n'
printf -- '- **Windows** (`*-windows.zip`): `.dll` natives only.\n\n'
printf 'Drop-in overlay for `left4dead2/`. All `.smx` plugins are recompiled '
printf 'from source with the upstream SourceMod 1.12 compiler '
printf '(rumblefrog/setup-sp); SourcePawn sources are not included in the '
printf 'archives.\n'
} > "$NOTES"

# --draft: nothing goes public (and the git tag is NOT created)
# until you review and click Publish on the Releases page.
# --generate-notes: appends a changelog built from merged PRs since
# the previous release (full history for the first one).
gh release create "$VER" \
--draft \
--generate-notes \
--target "$GITHUB_SHA" \
--title "$VER" \
--notes-file "$NOTES" \
$PRE \
"$LINUX_ASSET" "$WIN_ASSET"
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> [!IMPORTANT]
> It is recommended to host servers on Linux, but Windows is supported.
> When running Linux ensure that your setup is running a minimum of **`GLIBC 2.35`** (Ubuntu 22.04 or higher) or you will run into issues loading certain extensions.
> This repository only supports Sourcemod **1.12** and up (which comes with the repository for ease of use)
> This repository only supports Sourcemod **1.12** and up (which comes with the repository for ease of use)

---

Expand All @@ -26,7 +26,7 @@ In its current state it allows anyone to host their own up to date competitive L

> **Included Matchmodes:**

* **Zonemod 2.9e**
* **Zonemod 2.9.1b**
* **Zonemod Hunters**
* **Zonemod Retro**
* **NeoMod 0.4a**
Expand All @@ -38,6 +38,23 @@ In its current state it allows anyone to host their own up to date competitive L

---

## **Download & Installation:**

> [!IMPORTANT]
> Pick the archive that matches your **Server OS**:
> * **Linux:** `L4D2-Competitive-Rework-<version>-linux.tar.gz`
> * **Windows:** `L4D2-Competitive-Rework-<version>-windows.zip`

1. Download the latest archive from the [**Releases**](../../releases/latest) page.
2. Extract it directly into your server's **`left4dead2/`** directory.
3. For first-time server setup on dedicated servers, the [Dedicated Server Install Guide](Dedicated%20Server%20Install%20Guide/README.md) might be of use to you!

> [!NOTE]
> Releases only include what the servers need, **no** SourcePawn sources or compiler.
> To modify or recompile plugins, clone the repository instead.

---

## **Credits:**

> **Foundation/Advanced Work:**
Expand Down Expand Up @@ -103,6 +120,7 @@ In its current state it allows anyone to host their own up to date competitive L

* Aiden
* Derpduck
* Mart

> [!NOTE]
> If your work is being used and I forgot to credit you, don't hesitate to contact me on Discord (user: `sirplease`)
6 changes: 3 additions & 3 deletions addons/sourcemod/configs/matchmodes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
{
"zonemod"
{
"name" "ZoneMod 2.9.1"
"name" "ZoneMod 2.9.1b"
}
"zoneretro"
{
"name" "ZoneMod Retro 2.9.1"
"name" "ZoneMod Retro 2.9.1b"
}
"zm3v3"
{
Expand Down Expand Up @@ -109,7 +109,7 @@
{
"zonehunters"
{
"name" "ZoneHunters 2.9.1"
"name" "ZoneHunters 2.9.1b"
}
"zh3v3"
{
Expand Down
27 changes: 27 additions & 0 deletions addons/sourcemod/gamedata/l4d2_block_autoaim.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"Games"
{
"left4dead2"
{
"Functions"
{
"CBasePlayer::ShouldAutoaim"
{
"signature" "CBasePlayer::ShouldAutoaim"
"callconv" "thiscall"
"return" "bool"
"this" "entity"
}
}

"Signatures"
{
"CBasePlayer::ShouldAutoaim"
{
"library" "server"
"linux" "@_ZN11CBasePlayer13ShouldAutoaimEv"
"windows" "\x56\x8B\xF1\x8B\x06\x8B\x90\x74\x07\x00\x00\xFF\xD2\x84\xC0\x74\x2A\x32\xC0"
/* 56 8B F1 8B 06 8B 90 74 07 00 00 FF D2 84 C0 74 ?? 32 C0 */
}
}
}
}
15 changes: 15 additions & 0 deletions addons/sourcemod/gamedata/l4d2_fix_tank_rock_handoff.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"Games"
{
"left4dead2"
{
"Signatures"
{
"CThrow::OnStunned"
{
"library" "server"
"linux" "@_ZN6CThrow9OnStunnedEf"
"windows" "\x55\x8B\xEC\xF3\x0F\x10\x05\x2A\x2A\x2A\x2A\x56"
}
}
}
}
46 changes: 46 additions & 0 deletions addons/sourcemod/gamedata/l4d_fix_prop_los.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"Games"
{
"#default"
{
"Functions"
{
"l4d_fix_prop_los::CBaseProp::CalculateBlockLOS"
{
"signature" "CBaseProp::CalculateBlockLOS"
"callconv" "thiscall"
"return" "void"
"this" "entity"
}
}
}

"left4dead"
{
"Signatures"
{
"CBaseProp::CalculateBlockLOS"
{
"library" "server"
"linux" "@_ZN9CBaseProp17CalculateBlockLOSEv"
"windows" "\x83\xEC\x0C\x53\x55\x8B\xE9\x8B\x85\x2A\x2A\x2A\x2A\x8B"
// 83 EC 0C 53 55 8B E9 8B 85 ? ? ? ? 8B
}
}
}

"left4dead2"
{
"Signatures"
{
"CBaseProp::CalculateBlockLOS"
{
"library" "server"
"linux" "@_ZN9CBaseProp17CalculateBlockLOSEv"
"windows" "\x55\x8B\xEC\x83\xEC\x10\x53\x8B\xD9\x8B\x83\x2A\x2A\x2A\x2A\x8B"
// 55 8B EC 83 EC 10 53 8B D9 8B 83 ? ? ? ? 8B
// Search string "ai_addon_thrownprojectile"
// Called inside
}
}
}
}
Binary file modified addons/sourcemod/plugins/fixes/l4d2_fix_changelevel.smx
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified addons/sourcemod/plugins/optional/l4d2_hittable_control.smx
Binary file not shown.
Loading