Commit Graph
2105 Commits
Author SHA1 Message Date
Hut512 a5bfc2fa44 Make SteamEditWand event handlers public 2026-11-04 21:09:19 +01:00
Hut512 7140588f18 Rewrite SteamEditWand without packet filters 2026-11-04 21:09:19 +01:00
Hut512 5c47c8239f Remove netty Cursor render 2026-11-04 21:09:19 +01:00
Hut512 bf3a62e294 Remove obsolete AntiNocom 2026-11-04 21:09:03 +01:00
Hut512 77bac1f103 Make Smart Place thread safe 2026-11-04 21:08:55 +01:00
YoyoNow 937905f296 Merge pull request 'Hider core' (#519) from HiderCore into main
Reviewed-on: SteamWar/SteamWar#519
Reviewed-by: FessmLP <72+fessmlp@noreply.localhost>
2026-11-01 09:36:00 +01:00
YoyoNow dfec29dac5 Offer fight instead of local in /chat on arenas 2026-11-01 07:43:39 +01:00
YoyoNow b36d74da0e Fix WorldIdentifier 2026-11-01 07:35:56 +01:00
YoyoNow 65958b1fdb Fix WorldIdentifier 2026-11-01 07:12:13 +01:00
YoyoNow 24403488cd Merge pull request 'make world identifier valid by hex encoding them' (#521) from Jaki/SteamWar:main into main
Reviewed-on: SteamWar/SteamWar#521
2026-11-01 07:10:30 +01:00
Jakob Schulz 1389f81c7c make world identifier valid by hex encoding them 2026-11-01 00:46:13 +01:00
YoyoNow e550ee73f4 Answer private messages to yourself with an easter egg
Messaging yourself gets a random answer from your other self after ten
seconds, formatted like a normal private message, instead of "nobody
receives your message".
2026-10-31 23:42:43 +01:00
YoyoNow f882cc8c1b Merge pull request 'Add Wind Charge limit and region constraint' (#484) from Jaki/SteamWar:main into main
Reviewed-on: SteamWar/SteamWar#484
Reviewed-by: YoyoNow <4+yoyonow@noreply.localhost>
2026-10-31 23:27:31 +01:00
YoyoNow d4f4be78bb Add /whois click on names and /chat <channel> <message>
- Clicking a player name or @mention suggests /whois <player>; the
  hover explains the click
- /chat <channel> <message> writes once into a channel and replaces
  /chat <channel> msg <message>
- Clicking the Global or Local/Fight icon suggests /chat, for foreign
  arenas /chat <arena>
2026-10-31 23:24:00 +01:00
Jakob Schulz e22317f1fa optimize imports 2026-10-31 23:02:23 +01:00
Jakob Schulz ded46c28a6 change arena map identifier to not use gamemode 2026-10-31 22:50:54 +01:00
Jakob Schulz 641962ff01 change arena map identifier to arena/<... 2026-10-31 22:47:18 +01:00
Jakob Schulz d196f49ba2 Add arena map world name identifier for TowerRun and TNTLeague 2026-10-31 22:45:32 +01:00
Jakob Schulz 460d016295 Change naming to fight/<version>/<arenaMap> 2026-10-31 22:35:42 +01:00
YoyoNow 9eea5f5e25 Keep hidden block entities in chunks without their data
Hidden block entities were removed from chunk data, so the client did not
render blocks like shulker boxes at all. They are now sent with empty data,
hiding their contents but not the block itself.
2026-10-31 22:24:51 +01:00
YoyoNow 4dbe2ccac7 Speed up uncovering blocks in hulls
The steps that can lead into or past a changed block are computed once per
hull instead of searching all directions and parts on every block update,
which makes an update about three times faster.
2026-10-31 21:58:48 +01:00
YoyoNow d7d452ebe6 Let doors and trapdoors occlude in hulls
Doors and trapdoors do not occlude for the client, so they had no full face
in the hull and rays passed through closed trapdoors, revealing blocks behind
them along diagonals. Their face masks now come from their shape, so the face
their panel covers is full.
2026-10-31 21:37:08 +01:00
YoyoNow baa4cf34e5 Calculate hull visibility on block faces
Instead of a block occluding as a whole, the hull stores which of its six
faces are full, using the occlusion shapes the client culls faces with. A ray
inside a block can only leave it through an open face and enter the next
block through its open opposite face; if only that face is full, the ray
reaches its surface, so the block is visible, but stops there. Slabs, stairs
and stacked slabs now hide what is behind them; double slabs need no special
case anymore. Faces only open up on block updates, after which the rays that
could not get into, out of or past the block are continued.

Hidden blocks occlude by the same decision as the techhider, so waterlogged
blocks count as well when water is hidden. The hull therefore takes the
ObfuscationConfig, which the fight shares with its TechHiderWrapper.
2026-10-31 21:18:24 +01:00
YoyoNow e1ff37bea2 Apply the gamemode techhider with /hullhider
Players using /hullhider also get the techhider of the region's gamemode in
the build area, like in a fight: its hidden blocks are replaced and occlude
in the hull.
2026-10-31 20:09:45 +01:00
YoyoNow 5651455a5f Stop hull rays from passing between occluding blocks
A ray only moves diagonally if it could also reach the block by moving along
the single axes of the direction one after another without passing an
occluding block, so it no longer squeezes between blocks touching at an edge
or corner. When a block stops occluding, the diagonal rays it blocked are
continued, so incremental updates match a full initialisation.

Double slabs now occlude as well, as slab materials do not; block updates
pass the block data instead of the material for that.

To keep the initialisation fast, a ray only checks a diagonal step after the
cheaper checks, and the branch directions are computed once per hull.
2026-10-31 17:07:18 +01:00
YoyoNow 9fd2bd17d4 Use @LinkedTimer for the timers of linked classes
The repeating timers that linked classes and the plugin main classes started
once for the whole runtime now use @LinkedTimer, on Spigot (BauSystem,
SpigotCore, LobbySystem, MissileWars, TowerRun, Teamserver) and Velocity.
The FightInfoPacketSenders of MissileWars and TowerRun are linked themselves
instead of being started by the main class.
2026-10-31 16:26:34 +01:00
YoyoNow 9598b1c961 Add @LinkedTimer
A method of a linked class annotated with @LinkedTimer(delay, period) is run
repeatedly by the linker, on Spigot and Velocity. The method must not have
parameters, its return value is ignored. It is called through a MethodHandle
bound once when linking instead of reflection; LambdaMetafactory cannot be used
as the linker and the linked classes are in different class loaders.

The unit defaults to ticks and can be set to milliseconds up to hours; the
Unit enum converts it to ticks for Spigot and to a TimeUnit for Velocity.
HullHiderCommand uses it for its tick task.
2026-10-31 16:11:28 +01:00
YoyoNow b78fab3172 Stop the loader task and listener when a loader ends
Every loader started a timer and registered itself as listener, but neither
was stopped, so each loader kept running every tick until the server
restarted. Both are now stopped when the loader is stopped or replaced by a
new one.
2026-10-31 16:02:31 +01:00
YoyoNow d76c396268 Do not hide entities with the BauSystem hullhider
HullHider gets a hideEntities parameter: the fight still hides entities inside
hidden hulls, /hullhider only hides blocks. As the TechHider also dropped
spawn packets at hidden positions, ForPlayer#canAccessEntitySpawn decides
about them now, which the BauTechHider always allows.
2026-10-31 15:57:25 +01:00
YoyoNow edb13fb7df Stop registering linked listeners twice
ModifyCommand and WorldEditRenderer registered themselves as listener although
the SpigotLinker already does, so all their event handlers ran twice.
2026-10-31 15:43:35 +01:00
YoyoNow abf44b2306 Allow @Linked on fields
The value of a @Linked field of a linked class is linked like a linked class
itself, e.g. registered as listener, and unlinked again on unlink. The field
has to be initialised when linking. HullHiderCommand and TPSSystem use it
instead of registering their listeners by hand.
2026-10-31 15:43:35 +01:00
YoyoNow a9fbb4cd8d Combine techhider, xray and hullhider scoreboard lines
As only one of /techhider, /xray and /hullhider can be active per region,
the scoreboard shows them in a single "View" line naming the active one.
2026-10-31 15:36:02 +01:00
YoyoNow f02f356b2b Add /hullhider to BauSystem
/hullhider hides the inside of the build area hull of a region from the
players who toggle it, like the hull hider of a fight. Each region gets its
own hull while somebody uses it; it is rebuilt every time somebody enables it,
as WorldEdit and Axiom changes do not update it. /techhider, /xray and
/hullhider exclude each other per player and region.

Which players may see the hull contents is now decided by Viewers, a sealed
class with HiddenByDefault (fight) and VisibleByDefault (bau). Added players
are stored in a set; isViewer alone defines what being added means.
2026-10-31 15:32:18 +01:00
YoyoNow d1fb4ca67e Allow removing hulls and resend their chunks
HullHider#removeHull stops hiding a hull: it shows the entities and REntities
the hull hid and resends its chunks to everybody who could not view it. A hull
is enabled again by adding and initialising it.

Hull#resendChunks only resends chunks the player has loaded. HullHider now
resends the chunks to non-viewers after initialising a hull itself, so
FightHullHider no longer does it.
2026-10-31 15:09:04 +01:00
YoyoNow ce2a23f4b8 Migrate BauSystem to the new TechHider and remove the legacy TechHider
The new TechHider registers a permanent global filter, so BauSystem now uses
a single BauTechHider that combines the hiding rules of the spectator
techhider, /techhider and /xray per player. To support the different
obfuscation blocks of these rules, ForPlayer now provides the obfuscation
block per position.

The ChunkHider now also checks single valued chunk sections, which were sent
unfiltered before, and recalculates their block count if they change.
Unhandled packet types are logged once; statistics, debug samples and ping
responses are passed through.

The legacy TechHider and its access widener entries are removed.
2026-10-31 15:00:37 +01:00
YoyoNow 7d4252325a Extract obfuscation config into HiderCore
ObfuscationConfig resolves the hidden blocks, block states (including all
waterlogged states when water is hidden) and block entity types plus the
obfuscation block, either from a gamemode's techhider config or from plain
materials. TechHiderWrapper now only contains the fight specific access rules.
2026-10-31 14:50:32 +01:00
YoyoNow da4b684a4b Move Hull and generic HullHider into HiderCore
Hull no longer depends on FightSystem: plugin, world, region, ground
visibility and hidden blocks are passed in. HullRegion is the common block
box hulls work on. The generic HullHider<K> manages one hull per key and does
the block, entity and REntity tracking; FightHullHider keeps the fight
specific parts (team hulls, viewer rules, state dependent registration).

Entities are now checked against the hull with block coordinates, so entities
in the bottom layer and at the max z edge are handled correctly.
2026-10-31 14:49:00 +01:00
YoyoNow a3a97ee102 Move TechHider into new HiderCore module
HiderCore holds the TechHider, ChunkHider and AccessPrivilegeProvider so that
FightSystem and BauSystem can both shade it. BlockIds and ProtocolUtils stay in
SpigotCore (used by AntiNocom and RFallingBlockEntity) and move to
de.steamwar.core to avoid a split package. The access widener entries the
TechHider needs are duplicated into hidercore.accesswidener; the legacy
TechHider still needs its own copies in SpigotCore.
2026-10-31 14:44:55 +01:00
YoyoNow b8f61658f4 Cleanup Laufbau 2026-10-31 14:23:29 +01:00
YoyoNow 54f1ae0388 Merge pull request 'Hull hider fixes' (#517) from HullHiderFixes into main
Reviewed-on: SteamWar/SteamWar#517
2026-10-31 12:53:16 +01:00
YoyoNow fc090c2b48 Remove Hull primary direction 2026-10-31 12:49:28 +01:00
YoyoNow 6c99f1f9c9 Resend hull chunks to non-viewers after hull initialisation
Chunks encoded while the hull was filled as hidden contain obfuscated
blocks that become visible after initialize, and no block update is
generated for them. Reload the team's extend region for all players
that cannot see the hull.
2026-10-27 10:12:07 +01:00
YoyoNow ac7dc2d2d5 Use Mth.floor instead of int casts for TechHider coordinates
(int) truncates toward zero, so negative coordinates were checked
against the wrong block. Matches the server's block position math.
2026-10-27 10:10:18 +01:00
YoyoNow 865d28645a Stop filtering remove-entity packets in TechHider
Stripping ids of hidden entities left ghost entities on clients once
the entity became visible and was later removed. Removing an unknown
entity id is harmless, so the packet is passed through.
2026-10-27 10:10:09 +01:00
YoyoNow b47cff2805 Make TechHider hidden regions consistent for spectators
Spectators hid HiddenBlocks in the whole arena for block updates, but
full chunk packets outside both extend regions were sent unfiltered, so
the same blocks were hidden or visible depending on the packet type.

Hidden regions are now a list: spectators hide both team extend
regions, team members the opposite one. Block checks and the per-chunk
bypass use the same regions, so everything outside the extend regions
is visible and unfiltered.
2026-10-27 09:58:16 +01:00
YoyoNow 7cd2e540ef Make TechHider access checks player-scoped
AccessPrivilegeProvider#forPlayer returns a PlayerAccess that resolves
the player's hidden region once. TechHider creates it once per outer
packet (shared across bundle sub-packets) and passes it to every
processor, so all decisions within a packet are consistent and the
region/referee lookup no longer runs per block on the netty thread.
2026-10-27 09:50:59 +01:00
YoyoNow 8381cacdf8 Avoid NPE race when computing the TechHider hidden region
getHiddenRegion looked the player up in FightTeam.players twice (team,
then FightPlayer) on netty threads. A concurrent reset or removePlayer
made the second lookup return null, the NPE was swallowed by the global
filter and the packet was dropped. Resolve the FightPlayer once and
derive team and canEntern from it.
2026-10-27 09:28:05 +01:00
YoyoNow 4943682a66 Filter entity event packets by entity id in TechHider
The processor for ClientboundEntityEventPacket used getEventId(), the
status byte (2 = hurt, 3 = death, ...), as the entity id. Events of
hidden entities therefore passed the filter, and events of visible
entities could be dropped when an unrelated hidden entity had the same
id. Use the entityId field instead.
2026-10-27 09:24:45 +01:00
YoyoNow 0ef702da9e Hide hulls from players by default in HullHider
Hull kept a set of affected players that was only filled by a join
listener active in the Schem states, so spectators joining earlier were
never hidden from the hull. The set was also a plain HashSet read on
netty threads, where a racing lookup meant "not hidden".

Invert it into a concurrent set of viewers (referees, own team, boarded
players); everyone else is hidden by default.

- Hull: viewer UUID set with addViewer/removeViewer/forgetViewer, a
  null player counts as hidden
- Hull: entities are hidden/shown when they enter/leave the hull for all
  non-viewer online players; uncovered blocks go to non-viewers
- HullHider: join/quit handled in a listener active in every state; quit
  clears the viewer entry
- HullHider: TeamDeathEvent re-hides the enemy hull and resends its chunks
- FightPlayer: stop the enter countdown before firing TeamDeathEvent so
  listeners see canEntern() == false
2026-10-27 09:23:31 +01:00
YoyoNow 2ea09eadb2 Fix command errors being hidden by generic help (#513)
Commands ending in a String... parameter are treated as help commands.
When such a command failed with an @ErrorMessage (e.g. /msg or /kick
with an offline player), the generic help matched next, printed the
usage and the collected error was never shown.

Stop before generic help (noTabComplete) if an earlier help command
already collected errors, and print those instead.
2026-10-27 07:40:06 +01:00