Commit Graph

56 Commits

Author SHA1 Message Date
Houmgaor
eab7d1fc4f fix(channelserver): eliminate data races in shutdown and session lifecycle
The channel server had several concurrency issues found by the race
detector during isolation testing:

- acceptClients could send on a closed acceptConns channel during
  shutdown, causing a panic. Replace close(acceptConns) with a done
  channel and select-based shutdown signaling in both acceptClients
  and manageSessions.
- invalidateSessions read isShuttingDown and iterated sessions without
  holding the lock. Rewrite with ticker + done channel select and
  snapshot sessions under lock before processing timeouts.
- sendLoop/recvLoop accessed global _config.ErupeConfig.LoopDelay
  which races with tests modifying the global. Use the per-server
  erupeConfig instead.
- logoutPlayer panicked on DB errors and crashed on nil DB (no-db
  test scenarios). Guard with nil check and log errors instead.
- Shutdown was not idempotent, double-calling caused double-close
  panic on done channel.

Add 5 channel isolation tests verifying independent shutdown,
listener failure, session panic recovery, cross-channel registry
after shutdown, and stage isolation.
2026-02-20 14:36:37 +01:00
Houmgaor
754b5a3bff feat(channelserver): decouple channel servers for independent operation (#33)
Enable multiple Erupe instances to share a single PostgreSQL database
without destroying each other's state, fix existing data races in
cross-channel access, and lay groundwork for future distributed
channel server deployments.

Phase 1 — DB safety:
- Scope DELETE FROM servers/sign_sessions to this instance's server IDs
- Fix ci++ bug where failed channel start shifted subsequent IDs

Phase 2 — Fix data races in cross-channel access:
- Lock sessions map in FindSessionByCharID and DisconnectUser
- Lock stagesLock in handleMsgSysLockGlobalSema
- Snapshot sessions/stages under lock in TransitMessage types 1-4
- Lock channel when finding mail notification targets

Phase 3 — ChannelRegistry interface:
- Define ChannelRegistry interface with 7 cross-channel operations
- Implement LocalChannelRegistry with proper locking
- Add SessionSnapshot/StageSnapshot immutable copy types
- Delegate WorldcastMHF, FindSessionByCharID, DisconnectUser to Registry
- Migrate LockGlobalSema and guild mail handlers to use Registry
- Add comprehensive tests including concurrent access

Phase 4 — Per-channel enable/disable:
- Add Enabled *bool to EntranceChannelInfo (nil defaults to true)
- Skip disabled channels in startup loop, preserving ID stability
- Add IsEnabled() helper with backward-compatible default
- Update config.example.json with Enabled field
2026-02-19 18:13:34 +01:00
Houmgaor
99e544e0cf perf(channelserver): move UserBinary and minidata to memory-only
UserBinary type1-5 and EnhancedMinidata are transient session state
resent by the client on every login. Persisting them to the DB on
every set was unnecessary I/O. Both are now served exclusively from
server-scoped in-memory maps (userBinaryParts, minidataParts).

Includes a schema migration to drop the now-unused type2/type3
columns from user_binary and minidata column from characters.

Ref #158
2026-02-19 00:05:20 +01:00
Houmgaor
2bd5f98f32 docs: add doc.go files and godoc comments to all packages
Add package-level documentation (doc.go) to all 22 first-party
packages and godoc comments to ~150 previously undocumented
exported symbols across common/, network/, and server/.
2026-02-18 21:39:13 +01:00
Houmgaor
264b0ced6b refactor(channelserver): extract Raviente struct and methods into raviente.go
Consolidate Raviente-related code from sys_channel_server.go and
handlers_register.go into a dedicated file for better organization.
2026-02-18 19:38:22 +01:00
Houmgaor
a2609e26a0 fix: resolve 4 pre-existing test failures in channelserver
- Guard nil listener/acceptConns in Server.Shutdown() to prevent panic
  in test servers that don't bind a network listener
- Remove redundant userBinaryPartsLock in TestHandleMsgMhfLoaddata that
  caused a deadlock with handleMsgMhfLoaddata's own lock acquisition
- Increase test save blob size from 200 to 150000 bytes to accommodate
  ZZ save pointer offsets (up to 146728)
- Initialize MHFEquipment.Sigils[].Effects slices in test data to
  prevent index-out-of-range panic in SerializeWarehouseEquipment
- Insert warehouse row before updating it (UPDATE on 0 rows is not an
  error, so the INSERT fallback never triggered)
- Use COALESCE for nullable kouryou_point column in kill counter test
- Fix duplicate-add test expectation (CSV helper correctly deduplicates)
2026-02-18 15:59:36 +01:00
Houmgaor
c64dabc3ba fix: check all Close() return values for errcheck lint
Add explicit error discards (_ =) for Close() calls on network
connections, SQL rows, and file handles across 28 files. Also add
.golangci.yml with standard linter defaults to match CI configuration.
2026-02-17 23:57:14 +01:00
Houmgaor
2a0e3e2c84 fix: re-enable CI lint job and fix ~65 lint errors (partial)
Re-enable the golangci-lint job in CI (disabled Oct 2025), update to
Go 1.25 and golangci-lint-action v7. Fix errcheck, gosimple S1009,
staticcheck SA4031 and SA2001 errors across 54 files. Remaining ~39
lint errors will be addressed in follow-up commits.
2026-02-17 17:59:00 +01:00
Houmgaor
fb3e86f429 fix: handle Query/QueryRow/transaction errors in channel server handlers
Add error checking and logging for ~25 database call sites that were
silently dropping errors, preventing resource leaks (unclosed rows),
nil pointer panics, and silent data corruption in festa transactions.
2026-02-17 17:44:35 +01:00
Houmgaor
7dfc3e6049 Merge upstream/main into main
Resolve conflict in handlers_stage.go: keep lock-free packet
building pattern (copy session list, release lock, then build)
over upstream's in-lock QueueSendMHF approach.

Fix test compilation: remove objectIDs field references after
upstream removed it from Server struct.

Resync vendor directory with updated go.mod dependencies.
2026-02-16 11:31:42 +01:00
Houmgaor
1398383a8d fix(lint): automated linting, with simple formatter. 2025-10-19 22:43:05 +02:00
wish
c4ec2efde5 alpelo object system backport test commit 2025-10-05 16:18:22 +11:00
wish
aad3b088b9 alpelo object system backport test commit 2025-10-05 16:14:39 +11:00
wish
dd36f367a9 alpelo object system backport test commit 2025-10-05 16:10:47 +11:00
wish
f2862ea4b8 prevent concurrent map write to questCache 2025-03-08 11:41:57 +11:00
wish
3c0d29ed41 fix invalidateSessions 2025-02-27 20:06:05 +11:00
wish
7c61f70590 add invalidateSessions 2025-02-18 03:16:18 +11:00
wish
b20969ddc6 emulate retail semaphore logic 2024-10-03 21:56:06 +10:00
stratic-dev
3797438ca2 No database 2024-03-15 00:54:18 +00:00
stratic-dev
def2bc3d2c initial commit 2024-03-12 23:00:01 +00:00
wish
e0615dcd0c add support for operator accounts & bans 2024-01-03 19:08:45 +11:00
wish
ca80a98141 i18n proposal 2024-01-03 04:22:25 +11:00
Matthew
226adddc43 feat: Generate hashes for Discord and allow password resets 2023-11-26 16:47:54 -05:00
Matthew
33665130cf feat: Discord basic implementation 2023-11-26 01:22:51 -05:00
rockisch
0481b15b9b Allow signv2 response to be configured 2023-11-23 22:12:36 -03:00
wish
72bda06916 implement Quest caching 2023-11-16 21:51:28 +11:00
wish
15253cdc1f remove useless CIDs 2023-11-16 21:49:43 +11:00
wish
0f2edbf028 simplify & fix UpdateRavi 2023-10-03 23:05:45 +11:00
wish
4a35be488c rework Semaphores 2023-09-03 00:00:08 +10:00
wish
9f76d34e46 fix Raviente ID 2023-08-30 23:58:50 +10:00
wish
5b5621a3d8 fix and rework various Raviente ID systems 2023-08-30 23:43:56 +10:00
wish
42abdfb0c7 change getRaviSemaphore scope & handle RegisterEvent 2023-08-30 22:29:49 +10:00
wish
1685f409e7 initial ravi-v3 commit 2023-08-27 22:16:51 +10:00
wish
9642787631 rework Stage Object IDs 2023-07-29 22:35:08 +10:00
wish
a98ebf5d52 rewrite into SeasonOverride 2023-07-16 21:57:29 +10:00
wish
b4df642ee3 add ClientMode config option 2023-06-18 20:31:18 +10:00
wish
8df5697dd3 make raviente multiplier more accurate 2023-03-09 22:56:21 +11:00
wish
d5dc15fc93 implement guild semaphore locking 2023-03-09 17:31:43 +11:00
wish
67122eb908 rewrite broadcast functions 2023-02-12 15:56:04 +11:00
wish
717a34b5b9 implement automatic damage scaling for raviente 2023-02-04 22:41:06 +11:00
wish
85bff0cb19 raviente broadcast fixes 2022-11-12 13:09:59 +11:00
wish
624fc70910 add raviente broadcast translations 2022-11-12 10:43:53 +11:00
wish
10b2ddcfd7 map language to server instead of session 2022-11-09 23:50:40 +11:00
Yslan Ramos
63a829c913 refactor: change FindSessionByCharID to search on channel sessions 2022-08-27 20:05:25 -03:00
wish
f87c1e480f add missing static stages 2022-08-19 17:27:40 +10:00
wish
56ae30745d remove unused static stages 2022-08-18 00:23:48 +10:00
wish
14d3b37435 discord bot cleanup 2022-08-17 23:29:16 +10:00
wish
7a303d6e31 prevent use of reserved semaphore indexes 2022-08-14 19:03:11 +10:00
wish
08a7b91e11 handle TransitMessage 2022-08-05 01:57:56 +10:00
wish
3bdc206ff7 cast binary fixes 2022-08-04 02:46:04 +10:00