Koja Scripts

Security

What Koja Fishing validates on the server — fishing, shop, contracts, party, poaching and the admin panel — and how to connect its cheat detection to your anticheat.

Security

Koja Fishing treats the client as untrusted: everything that gives an item, money, XP or points is decided and checked on the server. This page lists what is validated, so you know what a modified client cannot do and where to hook your own anticheat.

What the server checks

SystemValidation
FishingThe fish is rolled on the server. A catch is accepted only for the fish that was rolled, only after the bite wait has passed, and only if the equipped line can hold its weight. Gear, bait, spot and level are checked when the cast starts.
Spot locksThe spot's requiredLevel, requireLicense, minRodTier and unlockFlag are checked on the server when the cast starts.
Keep / releaseOnly the fish waiting for a decision can be kept or released, once.
ShopPrices come from the server, including per-ped multipliers of the nearest shop ped. Requests must come from next to a shop ped, quantities are capped and merged per item, and the item's requiredLevel is enforced. The buy-back price of equipment is always below its cheapest sale price at that ped. Failed item deliveries are refunded.
Redeem codesOne use per player, an atomic use counter, a rate limit against guessing.
QuestsProgress is only added by server-side actions. Clients cannot add progress. Money and item rewards are given by the server when a quest completes.
Fishing guideMust be started next to the guide ped. The starter kit is given once per character (database flag). Finishing needs at least 30 seconds after the start and gives XP once.
HermitsDelivery only next to the hermit. Items are counted and removed on the server, the reward is given once per character, and removed items are given back if the reward cannot be delivered.
TournamentsPoints come from validated catches. Joining requires being at the tournament ped. Prizes are paid once, tracked in the database.
Licence examAnswers stay on the server, the time limit is enforced, attempts and cooldowns are stored.
Boat rentalLevel requirement, deposit and return position are checked on the server.
Diving cachesDistance to the cache, licence, one collection per spawn.
Diving centreUpgrades, refills and contracts only next to the diving ped, paid in cash checked on the server. A crate counts only at its server-generated position, underwater, once, and not earlier than 10 seconds after accepting the contract. Air reported by the client can only go down.
DiggingShovel, minimum dig time, maximum movement, cooldown. Gear modifiers come from the server.
Digging centreUpgrades and contracts only next to the digging ped. A contract cache counts only after a real dig, at its server-generated position, inside the contract area, once. The tutorial shovel is given once per character.
Electric fishingOwner-only actions, distance checks for placing, connecting and grabbing, one battery per player, one grab attempt per fish.
PartyInvites only to nearby players, leader-only actions, shared sale money split on the server, goal progress only from server-side catches, sales, dives and digs.
PoachingEvidence is recorded on the server from validated catches. Only players with a job from PoliceJobs (grade, duty) can inspect and fine, within InspectDistance. Offences need matching evidence, the total is capped by MaxFine, and the same angler has a cooldown.
Admin panelEvery request checks the ACE or group. Values are validated by type and range before they are saved, writes are rate-limited, and every change is logged to the server console.
All endpointsPer-player rate limits on every callback a client can spam.

Admin commands are console-only or ACE-protected — see Commands.

Reacting to cheat attempts

Every rejected request that can only come from a modified client calls Config.Security.OnSuspicious and prints a [security] line in the server console.

shared/config.main.lua
Config.Security = {
    ValidatePedDistance = true,
    PedInteractDistance = 10.0,
    OnSuspicious = function(source, reason)
        -- exports['your-anticheat']:flag(source, 'koja-fishing: ' .. reason)
    end,
}

reason is a short description such as fishing/catch: too fast.

Before you go live

  • Config.Debug = false — debug enables free-battery and test commands.
  • Config.Digging.EnableTestCommand = false.
  • Check that every sellPrice in config.items.lua is below price - maxPriceChange.
  • Grant command.fishingquest_test only to admins.
  • Grant koja-fishing.admin only to trusted staff, and check Config.Admin.Groups — the panel changes prices, rewards and players' data.