Skip to content

Instantly share code, notes, and snippets.

@NekoiNemo
Created July 13, 2024 18:01
Show Gist options
  • Save NekoiNemo/a56bd2608d9f63fe97a318f20c6f914b to your computer and use it in GitHub Desktop.
Save NekoiNemo/a56bd2608d9f63fe97a318f20c6f914b to your computer and use it in GitHub Desktop.
Peacock server - Linux notes

Site Latest release

A node.js based server emulator replacing official server for the Hitman 2016 series:

  • Hitman (2016)
  • Hitman Sniper Assassin
  • Hitman 2
  • Hitman 3 / World of Assassination

Installation

Download latest release (regular has Windows Node.js binaries bundled in, -linux doesn't).

Copy PeacockPatcher.exe into game directory (not strictly necessary, as it will patch a running process, not the executable next to it, but it's most convenient to call it from there in scripts)

Linux

To launch patcher together with the game, some adjustments are necessary.

First, copying patcher into game's dir is now mandatory for this method to work.

Also create the following Batch script WineLaunch.bat in the game's dir:

@echo off
start Launcher.exe %*
start PeacockPatcher.exe

This will make Proton launch both the game and the patcher at the same time

[!info] This will have patcher be launched interactively, and hang around after the game exists, keeping the "game" process alive in the Steam's eyes. [[#Non-interactive patcher|See alternative below]]

Change Steam's launch option to

bash -c 'exec "${@/Launcher.exe/WineLaunch.bat}"' -- %command%

This will substitute Launcher.exe with the script above in the chain of commands Steam normally executes to start the game through the Proton

Alternative wrapper

If something else needs to be done before/after starting the game (such as starting/stopping the Peacock server), an alternative wrapper script could be used.

Change Steam's launch option to

bash -c './wrapper.sh %command%'

Create the executable wrapper.sh in the game's directory:

#! /bin/bash

# comamnds before game starts, for example:
systemctl --user start peacock.service
# DO NOTE that any commands used here must either exit, or be forked, for script to actually reach the line below and start the game

$("${@/Launcher.exe/WineLaunch.bat}")

# commands after game (and patcher, if run interactively) exits, for example:
systemctl --user stop peacock.service

Usage

Start server (without specifying, it tries to run on port 80)

PORT=3000 node chunk0.js

When launching server for the first time, one should ideally download all assets from official servers (see [[#Tools]])

Start patcher. Enter the server address (default is localhost, on port 80 =_="). Patcher will save the last address used, but only the last one used. If you switch to IOI servers - address will need to be re-entered.

Start game.

Patcher should log that it has replaced server with specified.

Non-interactive patcher

Patcher can also be started in one-off headless mode from command line as

PeacockPatcher.exe --headless --domain "ip:port"

This will cause patcher to use the server provided to patch currently running Hitman process once, and exit, instead of hanging around (this option also doesn't allow re-patching for official servers!).

[!warning] Potential issues This will only patch the game once and exit. If no game process is available when patcher starts - it will just exit after doing nothing. Game should be launched with -skip_launcher option to avoid that happening

First launch and further purchases

When game has changes to owned content (such as when just purchased or when a DLC is added) - the actual installed game will know nothing about it (great job, IOI, fucking up a basic Steam feature) and game must be launched with stock IOI server once, fully logged in (for owned content proof to be saved locally), and then quit. After that it can be restarted and used with Peacock normally

Tools

There are two "tools": CLI and WebUI

CLI tool is for getting debug info, downloading official contracts, and pre-caching assets:

node chunk0.js tools

WebUI is available on the same port server is running on, without authentication. It allows starting escalation from specific level, creating loadouts, and importing official progress (but it seems to be broken right now)

Docker

Dockerfile

FROM node:18.18.2-alpine

ARG VERSION
ARG PORT=3000

WORKDIR /app

RUN mkdir userdata
RUN mkdir contractSessions
RUN mkdir contracts
RUN mkdir plugins
RUN mkdir images

RUN wget -q -O server.zip https://github.com/thepeacockproject/Peacock/releases/download/v${VERSION}/Peacock-v${VERSION}-linux.zip

RUN unzip -qd server server.zip \
    && mv server/Peacock-*/* ./ \
    && rm -rf server.zip server

RUN echo "#! /bin/sh" >> run.sh \
    && echo "export PORT=${PORT}" >> run.sh \
    && echo "node chunk0.js" >> run.sh \
    && chmod a+x run.sh

VOLUME /app/userdata
VOLUME /app/contractSessions
VOLUME /app/contracts
VOLUME /app/plugins
VOLUME /app/images

EXPOSE ${PORT}/tcp
EXPOSE ${PORT}/udp

CMD ["./run.sh"]

This will download a selected version from Github releases (alternatively, replace downloading with COPY as the same server.zip file from local storage), extracts it, and sets up a launcher fir the image.

Uses build args:

  • PORT - which port it will run on
  • VERSION - which version will be downloaded

Persisting data

  • userdata and contractSessions contain important user data and must always be persisted.
  • contracts contains automatically and manually downloaded contracts, and plugins - Peacock plugins to be added by the user. They are less important, but should probably still persisted.
  • images contains cached images for the various game menus. They are not necessary to persist, but would be nice to keep to increase autonomy
  • options.ini file must be placed in the working dir of the server, so it can't be made into a volume like the rest of the data.
    After the container is initially started, it must be copied out of the container with docker cp peacock-server:/app/options.ini ./. After that it must be mounted into a container from now on.

Usage

The patcher can later be obtained from the running container with docker cp peacock-server:/app/PeacockPatcher.exe ./

And tools accessed with docker exec -it peacock-server node chuck0.js tools

Compose example

name: "peacock"

services:

  server:
    image: peacock:7.3.1
    restart: unless-stopped
    ports:
      - 8450:3000
    volumes:
      - ./data/options.ini:/app/options.ini
      - ./data/userdata:/app/userdata
      - ./data/contracts:/app/contracts
      - ./data/plugins:/app/plugins
      - ./data/contractSessions:/app/contractSessions
      - ./data/images:/app/images

The last volume may be omitted, to cache into an automatically created volume.

With a build from Dockerfile:

  server:
    image: peacock:7.3.1
    pull_policy: never
    build:
      context: .
      dockerfile: Dockerfile
      args:
        VERSION: "7.3.1"
        PORT: 3000

Before docker compose up one should also do docker compose build, just in case. pull_policy: never is there to prevent docker from trying to download this image from the dockerhub (which will either not exist, or be a completely wrong image) first, and only then attempt to build it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment