Giter Site home page Giter Site logo

skeldjs / hindenburg Goto Github PK

View Code? Open in Web Editor NEW
35.0 35.0 13.0 33.6 MB

A scalable Among Us server written in typescript and made using SkeldJS.

License: GNU General Public License v3.0

TypeScript 97.10% Dockerfile 0.06% Shell 0.04% JavaScript 2.75% PowerShell 0.04%

hindenburg's Introduction

Skeld JS

Skeld JS

codecov license Lint and Test Build Docs

If you're looking for an Among Us server, check out my other project, Hindenburg

SkeldJS is a JavaScript implementation of the Among Us protocol and game, written in TypeScript.

Quick Start

See the Packages section for more installation information.

Features

🕵️‍♀️ Unopinionated

SkeldJS is completely unopinionated about the structure or use-case of your program, and can be used to develop clients or servers with no preference to either.

🔌 Extensible

With the power of a heavily event-based design, SkeldJS gives you the ability to extend or modify just about every aspect of its behaviour, even allowing you to create custom objects or roles.

🧩 Complete

SkeldJS is a complete implementation of everything in Among Us, and is designed to remain as close as possible to how the game actually functions, meaning you are never out of sync with the official clients, or missing out on important features.

⚡ Fast

SkeldJS uses lots of caching techniques and does no more work than absolutely necessary to remain as close as possible to the game.

Written in TypeScript

SkeldJS is written in TypeScript, not only meaning that there is a much less chance of bugs in your code, but also that you get full editor support for SkeldJS.

Packages

SkeldJS features several different packages, all focusing on different aspects of Among US development.

All of the below packages can be install with npm install --save <package name> or yarn add <package name>. For example, npm install --save @skeldjs/client.

SkeldJS does feature its own client, allowing you to connect with either the official servers, or any other Among Us server, supporting the 2 modes of authentication.

Several enums and constants in Among Us that are dumped directly from the game, and are used to ensure SkeldJS remains maintainable.

The core structures of SkeldJS, including many networked structures found in Among Us, and is the foundation for the client or any servers to build from.

Contains some useful general data to use in projects to make sense of task IDs, vent IDs, etc.

A basic DTLS socket implementation to communicate with the Among Us servers securely.

A utility package including a custom asynchronous and typed event emitter.

A tool to be used with the SkeldJS client to search for and join games on the local network.

A tool for the SkeldJS client to automatically navigate through the maps and make sense of the map colliders.

Lots of structures representing Among Us protocol byte structures, as well as providing a utility PacketDecoder class, acting similar to an event emitter.

Reactor integration for the SkeldJS client to register mods with a reactor-combatible server.

A light-weight wrapper on top of @skeldjs/core which takes in raw message buffers and translates them to be processed and to record state that trascends game data such as joining/leaving.

Contains a utility class for generating TMP in a readable code-based format, as well as a TMP parser and transpiler to HTML.

Allows you to convert game string IDs into a readable string in a language supported by Among Us, as well as supporting synthesising quick chat messages and cosmetic names.

Several utility classes and functions used in SkeldJS, separated as another module as they are unopinionated and are used all throughout.

Notes

The most comprehensive set of JavaScript protocol implementations for Among Us.

The following resources have been extremely useful in developing this project, and I suggest that you give the repositories a star if possible.

This repository is held under the GPL3 license, meaning I am not responsible for any consequences that may come from using the packages in SkeldJS.

hindenburg's People

Contributors

captain8771 avatar edqx avatar enderb0yhd avatar gabriel-nsiqueira avatar galster-dev avatar ilikeplayinggames avatar matadorprobr avatar peasplayer avatar toasty1307 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

hindenburg's Issues

Deprecate @HindenburgPlugin decorator

The @HindenburgPlugin decorator is mostly useless as it stands, for 2 reasons:

  • Currently it is just extra work for the plugin developer to have to keep the versions in the package.json and in the decorator in sync.
  • You can work out the plugin id and plugin version from the plugin's package.json

For the plugin load order, this can just be replaced with a @LoadOrder, which could even merge with the @PreventLoad decorator.

One thing I need to think about is how to keep the behaviour for the optional defaultConfig option that you can pass into the decorator. The most obvious solution seems to be a @DefaultConfig decorator, although this feels excessive somehow.

Movement Optimisations

  • Only send movement packets to players within vision range
  • Implement a configurable tick rate as part of the room config
  • Don't send dead player positions to alive players
  • Don't construct the packet, just write the same buffer straight to each socket

All configurable, of course.

This is in an attempt to make 40+ player rooms viable.

Plugin dependency API

An API to require dependencies for plugins to be properly loaded before loading itself.

Research a good algorithm to know, in which order, how to load plugins with dependencies, as well as banning circular dependencies.

This can either be done by analysing the plugin's package.json for hbplugin- packages (and actually verifying that they are valid plugins) or a @Dependency("hbplugin-*", required) decorator. It might be worth seeing if these can be combined, whereby the @Dependency decorator simply declares options/whether the dependency is required.

Note that the decorator does allow types to be enforced for the plugin, e.g. a this.dependencies.* object? (The types can't be inferred unfortunately due to a long standing typescript issue, but they can be enforced)

Build Error

Info

TypeScript Version: 4.2.4
Yarn version: 1.22.4
Node version: 14.3.0
Npm version: 7.6.0
Commit: 58abcf1

src/Room.ts:69:14 - error TS2341: Property '_interval' is private and only acessible within class 'Hostable<T>'.

|69| this._interval = setInterval(

Reproduction Steps

  1. git clone this repository
  2. Run yarn install to install dependencies
  3. Run yarn build to build server
  4. Build fails with error above

Hindenburg not working anymore (Among us Update)

Making this issue because among us just now updated and it broke Hindenburg

log

error: Unidentified (1, 2ms) sent a malformed packet
hindenburg~$ RangeError [ERR_OUT_OF_RANGE]: The value of "offset" is out of range. It must be >= 0 and <= 40. Received 41
    at new NodeError (node:internal/errors:371:5)
    at boundsError (node:internal/buffer:86:9)
    at Uint8Array.readUInt8 (node:internal/buffer:252:5)
    at HazelReader.uint8 (Hindenburg\node_modules\@skeldjs\util\lib\HazelReader.ts:89:34)
    at HazelReader.packed (Hindenburg\node_modules\@skeldjs\util\lib\HazelReader.ts:330:31)
    at Function.Deserialize (Hindenburg\src\packets\ModdedHelloPacket.ts:59:37)
    at PacketDecoder._parse (Hindenburg\node_modules\@skeldjs\protocol\lib\PacketDecoder.ts:544:44)
    at PacketDecoder._parse (Hindenburg\node_modules\@skeldjs\protocol\lib\PacketDecoder.ts:535:25)
    at PacketDecoder.parse (Hindenburg\node_modules\@skeldjs\protocol\lib\PacketDecoder.ts:583:21)
    at Worker.handleMessage (Hindenburg\src\Worker.ts:1537:47) {
  code: 'ERR_OUT_OF_RANGE'
}
i prob should have made this issue in skieldjs repo but eh

Build Errors 2

Four more build errors 😞

Info

Same versions as previous
Commit: 2963aed

src/util/format-player.ts:11:24 - error TS2339: Property 'info' does not exist on type 'PlayerData'.

|11| const colour = player.info ? player.info.color : Color.Grey;

src/util/format-player.ts:11:38 - error TS2339: Property 'info' does not exist on type 'PlayerData'.

|11| const colour = player.info ? player.info.color : Color.Grey;

src/util/format-player.ts:12:22 - error TS2339: Property 'info' does not exist on type 'PlayerData'.

|12| const name = player.info.name || "<No Name>" : "<No Data>";

src/util/format-player.ts:12:36 - error TS2339: Property 'info' does not exist on type 'PlayerData'.

|12| const name = player.info.name || "<No Name>" : "<No Data>";

I couldn't reopen the previous issue #4 :p

SaaH config options

Several options to fine-tune SaaH behaviour:

  • Option to make every player an acting host
  • Option to make no players acting hosts
  • "persistent" acting host; the host can re-join and still be the host

These could possibly be a plugin under hbplugin-saah-extensions

pt-BR (Portuguese Brazilian) Translation

image

So here it is:

export default {
    "havent_received_all_mods": {
        "pt_BR": "O servidor não conseguiu receber todos os seus mods, por favor tente novamente"
    },
    "reactor_required_on_server": {
        "pt_BR": "Este servidor requer que você tenha o Reactor, veja https://reactor.gg para mais informações"
    },
    "reactor_not_enabled_on_server": {
        "pt_BR": "O Reactor não está habilitado neste servidor, por favor desabilite-o"
    },
    "mod_banned_on_server": {
        // %1 = ID of mod that is banned
        "pt_BR": "Mod banido neste servidor: %1"
    },
    "reactor_required_for_room": {
        "pt_BR": "Está sala requer que você tenha o Reactor, veja https://reactor.gg para mais informações"
    },
    "reactor_not_enabled_for_room": {
        "pt_BR": "O Reactor não está habilitado nesta sala, por favor desabilite-o"
    },
    "missing_required_mod": {
        // %1 = ID of mod that is required
        // %2 = Version of the mod that is required
        "pt_BR": "Mod necessário faltando: %1 (%2)"
    },
    "bad_mod_version": {
        // %1 = ID of mod that has a bad version
        // %2 = The version of the mod that the client has
        // %3 = The version of the mod that the client needs
        "pt_BR": "Versão do mod ruim para %1: v%2, precisa v%3"
    },
    "mod_not_recognised": {
        // %1 = The ID of the mod that is not allowed
        "pt_BR": "Mod desconhecido não permitido: %1"
    }
} as const;

Fix perspective API

Perspective API has likely been heavily broken for the last few updates, it needs patching up.

"take it for a spin" button on the website

Hindenburg has a draft website here: https://hindenburg.vercel.app/

One idea that has obsessed me is the idea to have a "take it for a spin" button that temporarily hosts a Hindenburg server on a subdomain, e.g. xg9dat.hindenburg.io.

Consider the options:

Pros Cons
seems-cool Lots of work
Possibly high-cost
Will definitely get abused somehow
Borderline useless

Conclusion: It's a good idea

Jokes aside, there are things to keep in mind:

  • Servers could be kept alive at a max of 20 minutes and one per IP
  • Requiring OAuth with GitHub before starting the server could prevent abuse greatly
    • Could still allow for a super quick flow of "Take it For a Spin" -> Login with GitHub -> Server Starts, as GitHub OAuth is very streamlined.
    • Downside is that users might not have a GitHub account, perhaps try Discord OAuth or honestly a simple Captcha might do fine.
  • Probably mostly useless, although if I could write some interesting plugins to really show off Hindenburg, it could be very interesting. Especially if I give users access to the command line or an online dashboard.
    • Though this does make me wonder if it's even worth going through the effort, when it's 90% easier for me just to have a public Hindenburg instance running at all times..

Multiple plugin directories

Allow for multiple plugin locations, probably by passing a list of directories separated by a , in the HINDENBURG_PLUGINS environment variable.

Change Log

Fetch a changelog.json from the github repository if Hindenburg is outdated after checking for updates, and display them in the terminal.

Config to allow clients to broadcast unregistered messages

Currently you have to register messages if you want modded clients to be able to broadcast them. This doesn't apply to reactor Rpcs.

This requires re-creating the GameDataMessage packet to use an UnknownGameDataMessage if it's not found in the registered message map, then the server can choose later whether to broadcast that based on the configuration.

Packet limitting

Right now clients can send packets as often as they want. This leaves the server vulnerable to being flooded by script kiddies.

Hindenburg V1 Release

Below are the current goals for the release of Hindenburg v1, subject to change for as long as v1 has not released.

Rewrite Goals

Multiple hosts without SaaH

It's possible to re-use acting hosts logic to have multiple hosts in a game without SaaH. Remove host from acting hosts when a player joins, and add them back when that player has set their name.

API version feature

It would be nice to have some way to require a version for the api, so the plugin can make sure it is using the right code or even detect it is outdated.

Examples

Please add examaples of working code. For example the code of setting the server then getting the connection link or code.

Spawn prefab decorator: @SpawnPrefab

A decorator to be able to declare spawn prefabs on both the worker & room plugins:

Currently you have to register it on onPluginLoad which is a bit not nice.

async onPluginLoad() {
    this.room.registerPrefab(0x80, [  ]);
}

This is better:

@SpawnPrefab(0x80, [  ]);
export default class extends RoomPlugin {

}

Configuration Overwriting

Description

When starting the server with a config, it shows the crewmate ascii art like it has a config, but then says it couldn't find a config and overwrites the current config. The config before it was overwritten still takes place but since it is overwritten with the default config future server starts will use new config. It also overwrites the default config. It tells you to run it again to continue but still listens as a server. Without a config it doesn't show the ascii art, and creates the default config like normal.

Info

Node version 14.3.0
Yarn version 1.22.4
Commit 2963aed

Reproduction Steps

  1. Setup server
  2. Edit server config (or don't)
  3. Run yarn start:load-balancer
  4. Config is overwritten, server still listening

Media/Screenshot/Video

NOTE: .txt is on purpose to allow upload to GitHub
Before run (edited):
config.json.txt
After run (default): config.json.txt
Terminal screenshot: https://i.imgur.com/4UMb1n4.png

"Use an old version" when joining the game

I use Docker to build the server
docker run --name Hindenburg -p 22023:22023/udp hindenburg/hindenburg:latest

But when I enter the game, it prompts "You are running an older version of the game. Please update to play with others."
I have this on both the normal build (v2022.3.29s (build num 1864)) and the test build (v2022.2.24s)
Snipaste_2022-04-08_23-49-25
Snipaste_2022-04-08_23-52-46

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.