RegionResetRandomiser

  • community
  • administration
  • by trevor
  • Takaro main
  • all
Version
View export JSON

Trevor_RegionResetRandomiser: Map Region Reset Manager

The Trevor_RegionResetRandomiser module provides an intelligent solution for 7 Days to Die servers to maintain fresh gameplay experiences through automated region resets. This advanced Takaro module works with CPM to randomly select and reset map regions on a configurable schedule.

Key Benefits:

  • Reset Regions: Keeps the game world fresh with renewed resources in selected areas
  • Performance Optimization: Targeted resets help maintain server performance
  • Balanced Gameplay: Prevents complete resource depletion while preserving player builds
  • Selective Regeneration: Only resets a configurable subset of regions
  • Administrator Control: Allows manual triggering via Discord commands

Features:

  • Configurable number of regions to reset at each interval
  • Automatic daily region reset via cron job scheduling
  • Manual reset capability through Discord commands
  • Permission-based control with authorized user list
  • Custom activation phrase for manual triggering
  • Detailed debug logging to Discord channels
  • Smart region selection algorithm
  • Error handling for various edge cases
  • Unicode support for international player names
  • Timestamp logging for audit trails

Requires Prisma501's CPM mod for 7 Days to Die. Ideal for long-running servers that need region resets without full map resets.

Configuration 5

Settings you fill in when installing the module on a server.

SettingTypeDefaultDescription
resetQuantity required resetQuantity number 5 (Required) Specify the number of regions to randomly selected for reset. Must be fewer than the total number of flagged regions.
debugChannel debugChannel string "" (Optional) Supply a discord channel ID to receive debug activity messages.
authorisedPlayer authorisedPlayer string β€” People authorised to manually execute the hook via the discord debugChannel. Separate with commas. e.g.: Trevor, Barry, John Tested OK with unicode like πŸ†ƒπŸ†πŸ…΄πŸ†…πŸ…ΎπŸ† Not tested with odd symbols like: β˜• Catalysm
activationPhrase activationPhrase string "reset-regions" To manually trigger this module, the authorised person(s) can type this keyphrase into the Discord debugChannel specified above. e.g.: reset-regions
sendDebugMessages sendDebugMessages boolean false If enabled, debug messages will be sent to the debugChannel. The listening channel for keyphrase triggering is specified separately in the hook, below.
Raw config schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "resetQuantity"
  ],
  "additionalProperties": false,
  "properties": {
    "resetQuantity": {
      "title": "resetQuantity",
      "description": "(Required) Specify the number of regions to randomly selected for reset.\nMust be fewer than the total number of flagged regions.",
      "default": 5,
      "type": "number"
    },
    "debugChannel": {
      "title": "debugChannel",
      "description": "(Optional) Supply a discord channel ID to receive debug activity messages.",
      "default": "",
      "type": "string"
    },
    "authorisedPlayer": {
      "title": "authorisedPlayer",
      "description": "People authorised to manually execute the hook via the discord debugChannel. Separate with commas. e.g.:  Trevor, Barry, John\n\nTested OK with unicode like πŸ†ƒπŸ†πŸ…΄πŸ†…πŸ…ΎπŸ†\n\nNot tested with odd symbols like: β˜• Catalysm",
      "type": "string"
    },
    "activationPhrase": {
      "title": "activationPhrase",
      "description": "To manually trigger this module, the authorised person(s) can type this keyphrase into the Discord debugChannel specified above.  e.g.: reset-regions",
      "default": "reset-regions",
      "type": "string"
    },
    "sendDebugMessages": {
      "title": "sendDebugMessages",
      "description": "If enabled, debug messages will be sent to the debugChannel.\n\nThe listening channel for keyphrase triggering is specified separately in the hook, below.",
      "default": false,
      "type": "boolean"
    }
  }
}
Raw UI schema
{}

Hooks 1

Code that runs in reaction to a game or Takaro event.

  • randomiseResetRegions

    Hook for discord-message events

    Hook source
    import { data, takaro } from '@takaro/helpers';
    async function main() {
        const { module: mod } = data;
        const resetQuantity = mod.userConfig.resetQuantity;
        const debugChannel = mod.userConfig.debugChannel;
        const authorisedPlayer = mod.userConfig.authorisedPlayer;
        const activationPhrase = mod.userConfig.activationPhrase;
        const sendDebugMessages = mod.userConfig.sendDebugMessages;
        const randomRegionList = [];
    
        // Validate user-supplied discord channelIDs
        const validDebugChannel = debugChannel.length < 20 && /\d{18}/.test(debugChannel)
        // Helper function(s)
        function getTimeStamp() {
            const d = new Date();
            return `[${d.getFullYear()}-${d.getMonth()}-${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()} UTC]`;
        }
        function getRndInteger(min, max) {
            return Math.floor(Math.random() * (max - min)) + min;
        }
    
        if (validDebugChannel) {
            if (!data.eventData.author.isBot) {
                if (authorisedPlayer.includes(data.eventData.author.displayName)) {
                    if (data.eventData.msg === activationPhrase) {
                        // Get list of existing reset regions
                        const rawRegionList = (await takaro.gameserver.gameServerControllerExecuteCommand(data.gameServerId, { command: `mrr list` })).data.data.rawResult;
                        const fullRegionList = rawRegionList.split("\r\n");
                        fullRegionList.shift();
                        fullRegionList.pop();
    
                        if (validDebugChannel && sendDebugMessages) {
                            await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} Begin reset region process.` });
                        }
                        // Ensure there are some existing regions to work with
                        if (fullRegionList.length > 0) {
                            // Ensure there are enough existing regions to work with
                            if (fullRegionList.length > Number(resetQuantity)) {
    
                                // Make a random selection of regions to reset
                                for (let i = 0; i < resetQuantity; i++) {
                                    randomRegionList.push(fullRegionList[getRndInteger(0, Number(fullRegionList.length))]);
                                }
                                if (validDebugChannel && sendDebugMessages) {
                                    await takaro.discord.discordControllerSendMessage(debugChannel, { message: ` Prepared ${randomRegionList.length} regions for reset.` });
                                }
    
                                // Reset the randomised selection
                                if (randomRegionList.length > 0) {
                                    for (let i = 0; i < randomRegionList.length; i++) {
                                        const [a, x, z, b] = randomRegionList[i].split(".");
                                        await takaro.gameserver.gameServerControllerExecuteCommand(data.gameServerId, { command: `rr ${x} ${z} 2` });
                                    }
                                    if (validDebugChannel && sendDebugMessages) {
                                        await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} ${randomRegionList.length} regions were reset: ${randomRegionList.toString()}` });
                                    }
    
                                } else {
                                    if (validDebugChannel && sendDebugMessages) {
                                        await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} Something broke! Randomised selection is empty!` });
                                    }
                                }
                            } else {
                                if (validDebugChannel && sendDebugMessages) {
                                    await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} Can't select ${resetQuantity} regions from a list of ${fullRegionList.length} regions!` });
                                }
                            }
    
                        } else {
                            if (validDebugChannel && sendDebugMessages) {
                                await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} No reset regions are currently defined!` });
                            }
                        }
    
                        if (validDebugChannel && sendDebugMessages) {
                            await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} End reset region process.` });
                        }
                    }
                }
            }
        }
    }
    await main();

Cron jobs 1

Work the module runs on a schedule.

  • randomiseResetRegions

    Cron job source
    import { data, takaro } from '@takaro/helpers';
    async function main() {
        const { module: mod } = data;
        const resetQuantity = mod.userConfig.resetQuantity;
        const debugChannel = mod.userConfig.debugChannel;
        const sendDebugMessages = mod.userConfig.sendDebugMessages;
        const randomRegionList = [];
    
        // Validate user-supplied discord channelIDs
        const validDebugChannel = debugChannel.length < 20 && /\d{18}/.test(debugChannel)
        // Helper function(s)
        function getTimeStamp() {
            const d = new Date();
            return `[${d.getFullYear()}-${d.getMonth()}-${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()} UTC]`;
        }
        function getRndInteger(min, max) {
            return Math.floor(Math.random() * (max - min)) + min;
        }
    
        // Get list of existing reset regions
        const rawRegionList = (await takaro.gameserver.gameServerControllerExecuteCommand(data.gameServerId, { command: `mrr list` })).data.data.rawResult;
        const fullRegionList = rawRegionList.split("\r\n");
        fullRegionList.shift();
        fullRegionList.pop();
    
        if (validDebugChannel && sendDebugMessages) {
            await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} Begin reset region process.` });
        }
        // Ensure there are some existing regions to work with
        if (fullRegionList.length > 0) {
            // Ensure there are enough existing regions to work with
            if (fullRegionList.length > Number(resetQuantity)) {
    
                // Make a random selection of regions to reset
                for (let i = 0; i < resetQuantity; i++) {
                    randomRegionList.push(fullRegionList[getRndInteger(0, Number(fullRegionList.length))]);
                }
                if (validDebugChannel && sendDebugMessages) {
                    await takaro.discord.discordControllerSendMessage(debugChannel, { message: ` Prepared ${randomRegionList.length} regions for reset.` });
                }
    
                // Reset the randomised selection
                if (randomRegionList.length > 0) {
                    for (let i = 0; i < randomRegionList.length; i++) {
                        const [a, x, z, b] = randomRegionList[i].split(".");
                        await takaro.gameserver.gameServerControllerExecuteCommand(data.gameServerId, { command: `rr ${x} ${z} 2` });
                    }
                    if (validDebugChannel && sendDebugMessages) {
                        await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} ${randomRegionList.length} regions were reset: ${randomRegionList.toString()}` });
                    }
    
                } else {
                    if (validDebugChannel && sendDebugMessages) {
                        await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} Something broke! Randomised selection is empty!` });
                    }
                }
            } else {
                if (validDebugChannel && sendDebugMessages) {
                    await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} Can't select ${resetQuantity} regions from a list of ${fullRegionList.length} regions!` });
                }
            }
    
        } else {
            if (validDebugChannel && sendDebugMessages) {
                await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} No reset regions are currently defined!` });
            }
        }
    
        if (validDebugChannel && sendDebugMessages) {
            await takaro.discord.discordControllerSendMessage(debugChannel, { message: `${getTimeStamp()} End reset region process.` });
        }
    }
    await main();