
Editor’s Note:
For our cluster, I simply setup a Scheduled Task to run every 90 minutes, which executed the ‘raffle’ command within a git-bash environment, running a fully automated periodic raffle.
Optional Setup: Excluded Players
Should you wish to exclude specific players, such as admins, you can enter their EOSID’s in the config under the excluded players heading, so they are excluded from winning the raffle
Dependencies:
Extended Rcon – Because Wildcard’s implementation of giving items via console/rcon is COMPLETELY broken, the Extended Rcon plugin is a requirement so the raffle script can utilize it’s “GiveItemToEOSId” Rcon command.
(newer version available via the developer’s discord)
mcrcon – or whichever Rcon agent you prefer
Description:
CLI for running and maintaining raffles within an Ark Ascended Cluster.
Raffle will first check for 5 or more players, if met, a raffle is run
Flags to force a raffle regardless of online players are available
Options:
raffle ──── Run a regular raffle (Required: 5 Players)
raffle -f ──── Force a raffle, regardless of how many online players
raffle -l ──── View the last 150 lines of the Raffle log
raffle -w ──── View the last 100 lines of the Winners Log
raffle -v ──── Check Raffle CLI Version
Examples:
raffle
raffle -f
#!/usr/bin/env bash
#
#
set -euo pipefail
#######################
# RAFFLE CONFIGURATIONS
#######################
serverIP="YOUR-SERVER-IP"
mcrcon="/c/Ark/mcrcon/mcrcon.exe"
rconpass="YOUR-RCON-PASS"
# Minimum numbers of players required for a raffle to be drawn
min_players="5"
logFile="/c/Ark/Logs/raffle-log.txt"
winnerLog="/c/Ark/Logs/raffle-winners.txt"
#################################
# SERVER ARRAYS
#################################
SERVERS=(
Island
Ragnarok
Astraeos
Extinction
Aberration
Genesis1
)
declare -A SERVER_PORT=(
[Island]=1234
[Ragnarok]=1234
[Astraeos]=1234
[Extinction]=1234
[Aberration]=1234
[Genesis1]=1234
)
declare -A SERVER_PASS=(
[Island]="$rconpass"
[Ragnarok]="$rconpass"
[Astraeos]="$rconpass"
[Extinction]="$rconpass"
[Aberration]="$rconpass"
[Genesis1]="$rconpass"
)
#################################
# EXCLUDED PLAYERS
#################################
declare -A EXCLUDED=(
# APlayerName
[00012341234123412341234123412341]=1 # < Excluded Player's EOSID
# APlayerName
[00012341234123412341234123412341]=1 # < Excluded Player's EOSID
)
#
# END CONFIGURATION
#
#######################
# LOGGING
#######################
mkdir -p \
"$(dirname "$logFile")" \
"$(dirname "$winnerLog")"
#######################
# GLOBAL VARIABLES
#######################
OnlinePlayerCount=0
version="3.4.8"
####################
# COLOUR VARIABLES
####################
# Terminal Formatting
RESET="\033[0m"
BOLD="\033[1m"
# UI Colours
CLR_RED="\033[38;5;196m" # Bright Red
CLR_GREEN="\033[38;5;46m" # Bright Lime Green
CLR_GOLD="\033[38;5;226m" # Gold
CLR_PURPLE="\033[38;5;141m" # Light Purple / Lavender
CLR_BLUE="\033[38;5;69m" # Bright Sky Blue
CLR_DGREEN="\033[38;5;2m" # Dark Forest Green
CLR_ORANGE="\033[38;5;208m" # Orange
CLR_AQUA="\033[38;5;51m" # Aqua
CLR_TEXT="\033[38;5;255m" # Light Grey
CLR_FRAME="${BOLD}\033[38;5;250m" # Darker Grey
CLR_TITLE="\033[38;5;147m" # Light Grey (optional)
#################################
# PRIZE PACK FUNCTIONS
#################################
PrizePacks=(
Prize_CryoPack_Large
Prize_CryoPack_Small
Prize_CryoPack_Small
Prize_Elec250
Prize_Element
Prize_ElementDust
Prize_ElementDust
Prize_ElementDust
Prize_ElementShards
Prize_ElementShards
Prize_ElementShards
Prize_Polymer500
Prize_ResourcePack
Prize_ShotgunPack
Prize_ChainsawPack
Prize_Shit_Large
Prize_indforge
Prize_Cons_Mindwipe
Prize_Cons_Cake
Prize_Cons_Narcotic
Prize_Cons_Honey
Prize_Cons_PrimeJerky
Prize_Cons_PrimeFish
Prize_Points
Prize_Points
Prize_ConsumablesPack
Prize_AdvancedRifleAmmo
Prize_SniperAmmo
Prize_SniperAmmo
Prize_ShotgunShells
Prize_ShotgunShells
Prize_LazarusChowders
Prize_FriaCurry
Prize_MedicalBrews
Prize_CookedMutton
Prize_ExtraordinaryKibble
Prize_ExceptionalKibble
Prize_Sap
Prize_RareFlowers
Prize_Armour2pc
Prize_RandomSaddle
Prize_RandomSaddle
Prize_RandomChibi
Prize_RandomChibi
Prize_RandomChibi
)
Armour_Flak=(
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Metal/PrimalItemArmor_MetalHelmet.PrimalItemArmor_MetalHelmet"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Metal/PrimalItemArmor_MetalShirt.PrimalItemArmor_MetalShirt"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Metal/PrimalItemArmor_MetalGloves.PrimalItemArmor_MetalGloves"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Metal/PrimalItemArmor_MetalPants.PrimalItemArmor_MetalPants"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Metal/PrimalItemArmor_MetalBoots.PrimalItemArmor_MetalBoots"
)
Armour_Ghillie=(
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Ghillie/PrimalItemArmor_GhillieHelmet.PrimalItemArmor_GhillieHelmet"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Ghillie/PrimalItemArmor_GhillieShirt.PrimalItemArmor_GhillieShirt"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Ghillie/PrimalItemArmor_GhillieGloves.PrimalItemArmor_GhillieGloves"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Ghillie/PrimalItemArmor_GhilliePants.PrimalItemArmor_GhilliePants"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Ghillie/PrimalItemArmor_GhillieBoots.PrimalItemArmor_GhillieBoots"
)
Armour_Hazmat=(
"/Game/Aberration/CoreBlueprints/Items/Armor/HazardSuit/PrimalItemArmor_HazardSuitHelmet.PrimalItemArmor_HazardSuitHelmet"
"/Game/Aberration/CoreBlueprints/Items/Armor/HazardSuit/PrimalItemArmor_HazardSuitShirt.PrimalItemArmor_HazardSuitShirt"
"/Game/Aberration/CoreBlueprints/Items/Armor/HazardSuit/PrimalItemArmor_HazardSuitGloves.PrimalItemArmor_HazardSuitGloves"
"/Game/Aberration/CoreBlueprints/Items/Armor/HazardSuit/PrimalItemArmor_HazardSuitPants.PrimalItemArmor_HazardSuitPants"
"/Game/Aberration/CoreBlueprints/Items/Armor/HazardSuit/PrimalItemArmor_HazardSuitBoots.PrimalItemArmor_HazardSuitBoots"
)
Saddles=(
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_ArgentavisSaddle.PrimalItemArmor_ArgentavisSaddle"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_RexSaddle.PrimalItemArmor_RexSaddle"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_YutySaddle.PrimalItemArmor_YutySaddle"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_TherizinosaurusSaddle.PrimalItemArmor_TherizinosaurusSaddle"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_MaewingSaddle.PrimalItemArmor_MaewingSaddle"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_DoedSaddle.PrimalItemArmor_DoedSaddle"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_AnkyloSaddle.PrimalItemArmor_AnkyloSaddle"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Saddles/PrimalItemArmor_PteroSaddle.PrimalItemArmor_PteroSaddle"
)
Chibis=(
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_SnowOwl.PrimalItemSkin_ChibiDino_SnowOwl"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_TophatKairuku.PrimalItemSkin_ChibiDino_TophatKairuku"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Raptor_Bone.PrimalItemSkin_ChibiDino_Raptor_Bone"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Trike.PrimalItemSkin_ChibiDino_Trike"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Raptor.PrimalItemSkin_ChibiDino_Raptor"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Pulmonoscorpius.PrimalItemSkin_ChibiDino_Pulmonoscorpius"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Pteranodon.PrimalItemSkin_ChibiDino_Pteranodon"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Phiomia.PrimalItemSkin_ChibiDino_Phiomia"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Sheep.PrimalItemSkin_ChibiDino_Sheep"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Otter.PrimalItemSkin_ChibiDino_Otter"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Mantis.PrimalItemSkin_ChibiDino_Mantis"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Lymantria.PrimalItemSkin_ChibiDino_Lymantria"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Mesopithecus.PrimalItemSkin_ChibiDino_Mesopithecus"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Dodo.PrimalItemSkin_ChibiDino_Dodo"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Anglerfish.PrimalItemSkin_ChibiDino_Anglerfish"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Ammonite.PrimalItemSkin_ChibiDino_Ammonite"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Achatina.PrimalItemSkin_ChibiDino_Achatina"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Reindeer.PrimalItemSkin_ChibiDino_Reindeer"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_WoollyRhino.PrimalItemSkin_ChibiDino_WoollyRhino"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_RockGolem.PrimalItemSkin_ChibiDino_RockGolem"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Saber.PrimalItemSkin_ChibiDino_Saber"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Sarco.PrimalItemSkin_ChibiDino_Sarco"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Stego.PrimalItemSkin_ChibiDino_Stego"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Tapejara.PrimalItemSkin_ChibiDino_Tapejara"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Megalodon.PrimalItemSkin_ChibiDino_Megalodon"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Megatherium.PrimalItemSkin_ChibiDino_Megatherium"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Onyc.PrimalItemSkin_ChibiDino_Onyc"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Paraceratherium.PrimalItemSkin_ChibiDino_Paraceratherium"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Procoptodon.PrimalItemSkin_ChibiDino_Procoptodon"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Ankylosaurus.PrimalItemSkin_ChibiDino_Ankylosaurus"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Araneo.PrimalItemSkin_ChibiDino_Araneo"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Argent.PrimalItemSkin_ChibiDino_Argent"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Baryonyx.PrimalItemSkin_ChibiDino_Baryonyx"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Basilisk.PrimalItemSkin_ChibiDino_Basilisk"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Bronto.PrimalItemSkin_ChibiDino_Bronto"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Carnotaurus.PrimalItemSkin_ChibiDino_Carnotaurus"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Castroides.PrimalItemSkin_ChibiDino_Castroides"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Daeodon.PrimalItemSkin_ChibiDino_Daeodon"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Diplodocus.PrimalItemSkin_ChibiDino_Diplodocus"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Direbear.PrimalItemSkin_ChibiDino_Direbear"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Direwolf.PrimalItemSkin_ChibiDino_Direwolf"
"/Game/PrimalEarth/CoreBlueprints/Items/Armor/Skin/ChibiDinos/PrimalItemSkin_ChibiDino_Doedicurus.PrimalItemSkin_ChibiDino_Doedicurus"
)
Prize_RandomChibi() {
PrizeName="A Random Chibi Selection!"
PrizeCommands=()
local Chibi
Chibi="${Chibis[RANDOM % ${#Chibis[@]}]}"
PrizeCommands+=(
"GiveItemToEOSID {PLAYER} '$Chibi' 1 0 0"
)
}
Prize_RandomSaddle() {
PrizeName="A Random Saddle Selection!"
PrizeCommands=()
local Saddle
local Quality
Saddle="${Saddles[RANDOM % ${#Saddles[@]}]}"
# 66.7% quality 5, 22.2% quality 10, 11.1% quality 20
local Qualities=(5 5 5 5 5 5 10 10 20)
Quality="${Qualities[RANDOM % ${#Qualities[@]}]}"
PrizeCommands+=(
"GiveItemToEOSID {PLAYER} '$Saddle' 1 $Quality 0"
)
}
Prize_Armour2pc() {
PrizeName="2 Piece Armour Pack"
PrizeCommands=()
local PieceCount=2
local ArmourTypes=(Flak Ghillie Hazmat)
SelectedType=${ArmourTypes[RANDOM % ${#ArmourTypes[@]}]}
local -n Set="Armour_${SelectedType}"
mapfile -t Picks < <(
printf '%s\n' "${Set[@]}" |
shuf |
head -"${PieceCount}"
)
echo "Selected armour type: $SelectedType"
local Qualities=(5 5 5 5 5 5 10 10 20)
local Quality="${Qualities[RANDOM % ${#Qualities[@]}]}"
for item in "${Picks[@]}"; do
echo " $item"
done
for item in "${Picks[@]}"; do
PrizeCommands+=(
"GiveItemToEOSID {PLAYER} '$item' 1 $Quality 0"
)
done
}
Prize_ResourcePack() {
PrizeName="Resource Prize Pack"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Element.PrimalItemResource_Element' 25 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Gunpowder.PrimalItemResource_Gunpowder' 500 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Polymer.PrimalItemResource_Polymer' 500 0 0"
#"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_BlackPearl.PrimalItemResource_BlackPearl' 100 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Electronics.PrimalItemResource_Electronics' 150 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_ChitinPaste.PrimalItemResource_ChitinPaste' 500 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Oil.PrimalItemResource_Oil' 500 0 0"
)
}
Prize_Element() {
PrizeName="25 Element"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Element.PrimalItemResource_Element' 25 0 0"
)
}
Prize_ElementDust() {
PrizeName="5000 Element Dust"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/Extinction/CoreBlueprints/Resources/PrimalItemResource_ElementDust.PrimalItemResource_ElementDust' 5000 0 0"
)
}
Prize_ElementShards() {
PrizeName="500 Element Shards"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_ElementShard.PrimalItemResource_ElementShard' 500 0 0"
)
}
Prize_MetalArmorset() {
PrizeName="[Ascendant] Complete Flak Armor Set"
PrizeCommands=(
"GiveArmorSet {PLAYER} Metal Asc"
)
}
Prize_ShotgunPack() {
PrizeName="[Ascendant] Shotgun Prize Pack"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Weapons/PrimalItem_WeaponMachinedShotgun.PrimalItem_WeaponMachinedShotgun' 1 10 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Weapons/PrimalItemAmmo_SimpleShotgunBullet.PrimalItemAmmo_SimpleShotgunBullet' 10 0 0"
)
}
Prize_ChainsawPack() {
PrizeName="[Ascendant] Chainsaw Prize Pack"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/ScorchedEarth/WeaponChainsaw/PrimalItem_ChainSaw.PrimalItem_ChainSaw' 1 10 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Gasoline.PrimalItemResource_Gasoline' 100 0 0"
)
}
Prize_CryoPack_Small() {
PrizeName="5 Cryopods"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/Extinction/CoreBlueprints/Weapons/PrimalItem_WeaponEmptyCryopod.PrimalItem_WeaponEmptyCryopod' 5 0 0"
)
}
Prize_CryoPack_Large() {
PrizeName="Cryogenic Prize Pack"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/Extinction/CoreBlueprints/Weapons/PrimalItem_WeaponEmptyCryopod.PrimalItem_WeaponEmptyCryopod' 10 0 0"
"GiveItemToEOSID {PLAYER} '/Game/Extinction/CoreBlueprints/Items/PrimalItemStructure_CryoFridge.PrimalItemStructure_CryoFridge' 1 0 0"
)
}
Prize_Polymer500() {
PrizeName="500 Polymer"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Polymer.PrimalItemResource_Polymer' 500 0 0"
)
}
Prize_Elec250() {
PrizeName="150 Electronics"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Electronics.PrimalItemResource_Electronics' 150 0 0"
)
}
Prize_Shit_Large() {
PrizeName="200 Individual Large Dino Shits"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_DinoPoopLarge.PrimalItemConsumable_DinoPoopLarge' 200 0 0"
)
}
Prize_indforge() {
PrizeName="An Industrial Forge"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Structures/Misc/PrimalItemStructure_IndustrialForge.PrimalItemStructure_IndustrialForge' 1 0 0"
)
}
Prize_Cons_Mindwipe() {
PrizeName="A Forgetty potion"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/BaseBPs/PrimalItemConsumableRespecSoup.PrimalItemConsumableRespecSoup' 1 0 0"
)
}
Prize_Cons_Cake() {
PrizeName="10 Sweet Vegetable Cakes"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_SweetVeggieCake.PrimalItemConsumable_SweetVeggieCake' 10 0 0"
)
}
Prize_Cons_Narcotic() {
PrizeName="250 Narcotic"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Narcotic.PrimalItemConsumable_Narcotic' 250 0 0"
)
}
Prize_Cons_Honey() {
PrizeName="100 Honey"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Honey.PrimalItemConsumable_Honey' 100 0 0"
)
}
Prize_Cons_PrimeJerky() {
PrizeName="20 Prime Meat Jerky"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_CookedPrimeMeat_Jerky.PrimalItemConsumable_CookedPrimeMeat_Jerky' 20 0 0"
)
}
Prize_Cons_PrimeFish() {
PrizeName="25 Prime Fish Meat"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_RawPrimeMeat_Fish.PrimalItemConsumable_RawPrimeMeat_Fish' 25 0 0"
)
}
Prize_Points() {
PrizeName="5 Shop Points!"
PrizeCommands=(
"AddPoints {PLAYER} 5"
)
}
Prize_ConsumablesPack() {
PrizeName="Consumables Pack - 5 of Each Soup"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_CalienSoup.PrimalItemConsumable_Soup_CalienSoup' 5 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_FriaCurry.PrimalItemConsumable_Soup_FriaCurry' 5 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_FocalChili.PrimalItemConsumable_Soup_FocalChili' 5 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_EnduroStew.PrimalItemConsumable_Soup_EnduroStew' 5 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_LazarusChowder.PrimalItemConsumable_Soup_LazarusChowder' 5 0 0"
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_ShadowSteak.PrimalItemConsumable_Soup_ShadowSteak' 5 0 0"
)
}
Prize_Sap() {
PrizeName="100 Sap"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_Sap.PrimalItemResource_Sap' 100 0 0"
)
}
Prize_RareFlowers() {
PrizeName="250 Rare Flowers"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Resources/PrimalItemResource_RareFlower.PrimalItemResource_RareFlower' 250 0 0"
)
}
Prize_AdvancedRifleAmmo() {
PrizeName="150 Advanced Rifle Bullets"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Weapons/PrimalItemAmmo_AdvancedRifleBullet.PrimalItemAmmo_AdvancedRifleBullet' 150 0 0"
)
}
Prize_SniperAmmo() {
PrizeName="100 Sniper Bullets"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Weapons/PrimalItemAmmo_SimpleRifleBullet.PrimalItemAmmo_SimpleRifleBullet' 100 0 0"
)
}
Prize_ShotgunShells() {
PrizeName="100 Shotgun Shells"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Weapons/PrimalItemAmmo_ShotgunShell.PrimalItemAmmo_ShotgunShell' 100 0 0"
)
}
Prize_MedicalBrews() {
PrizeName="50 Medical Brews"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_HealSoup.PrimalItemConsumable_HealSoup' 50 0 0"
)
}
Prize_LazarusChowders() {
PrizeName="5 Lazarus Chowders"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_LazarusChowder.PrimalItemConsumable_Soup_LazarusChowder' 5 0 0"
)
}
Prize_FriaCurry() {
PrizeName="5 Fria Curry"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Soup_FriaCurry.PrimalItemConsumable_Soup_FriaCurry' 5 0 0"
)
}
Prize_CookedMutton() {
PrizeName="500 Cooked Lamb Chops"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_CookedLambChop.PrimalItemConsumable_CookedLambChop' 500 0 0"
)
}
Prize_ExtraordinaryKibble() {
PrizeName="10 Extraordinary Kibble"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Kibble_Base_Special.PrimalItemConsumable_Kibble_Base_Special' 10 0 0"
)
}
Prize_ExceptionalKibble() {
PrizeName="10 Exceptional Kibble"
PrizeCommands=(
"GiveItemToEOSID {PLAYER} '/Game/PrimalEarth/CoreBlueprints/Items/Consumables/PrimalItemConsumable_Kibble_Base_XLarge.PrimalItemConsumable_Kibble_Base_XLarge' 10 0 0"
)
}
#######################
# FUNCTIONS
#######################
timestamp() {
local message="$1"
local colour="${2:-}"
local line
line="$(date '+%F %T') - $message"
echo -e "${colour}${line}${RESET}" >&2
}
send_rcon() {
local server=$1
local command=$2
local result
result=$(
"$mcrcon" \
-H "$serverIP" \
-P "${SERVER_PORT[$server]}" \
-p "${SERVER_PASS[$server]}" \
"$command" 2>&1 |
sed -E 's/\x1B\[[0-9;]*[[:alpha:]]//g'
)
#timestamp "[$server] $command -> $result"
printf '%s\n' "$result"
}
check_player_num() {
OnlinePlayerCount=0
echo
echo -e "${CLR_GOLD} ▶ Checking total connected players${RESET}"
echo
for servername in "${!SERVER_PORT[@]}"; do
# Calculate total online on cluster
onlineNum=$(send_rcon "$servername" getonlinenum)
OnlinePlayerCount=$((OnlinePlayerCount + onlineNum))
echo "${servername}: $onlineNum Players"
done
echo
echo -e " ▶ Total Players Online: ${CLR_GOLD}${OnlinePlayerCount}${RESET}"
echo
}
broadcast_all() {
local message=$1
for server in "${ACTIVE_SERVERS[@]}"; do
send_rcon "$server" "Broadcast $message" >/dev/null
done
}
chat_all() {
local message=$1
for server in "${ACTIVE_SERVERS[@]}"; do
send_rcon "$server" "ServerChat $message" >/dev/null
done
}
get_active_servers() {
ACTIVE_SERVERS=()
for server in "${SERVERS[@]}"; do
local result
result=$(send_rcon "$server" "ListPlayers")
[[ $result == *"No Players Connected"* ]] && continue
ACTIVE_SERVERS+=("$server")
done
}
get_online_players() {
PLAYERS=()
declare -gA PLAYER_NAME=()
declare -gA PLAYER_SERVER=()
local -A seen=()
for server in "${SERVERS[@]}"; do
timestamp "Querying players on $server"
local result
result=$(send_rcon "$server" "ListPlayers")
[[ $result == *"No Players Connected"* ]] && continue
while IFS= read -r line; do
# Remove ANSI escape sequences
line=$(sed -E 's/\x1B\[[0-9;]*[[:alpha:]]//g' <<<"$line")
# Trim trailing whitespace
line="${line%"${line##*[![:space:]]}"}"
[[ $line =~ ^[0-9]+\.[[:space:]]*([^,]+),[[:space:]]*([a-fA-F0-9]{32})$ ]] || continue
local name="${BASH_REMATCH[1]}"
local id="${BASH_REMATCH[2]}"
name="${name#"${name%%[![:space:]]*}"}"
name="${name%"${name##*[![:space:]]}"}"
[[ ${EXCLUDED[$id]+x} ]] && {
timestamp "Excluded player: $name [$id]" "$CLR_ORANGE"
continue
}
[[ ${seen[$id]+x} ]] && continue
seen[$id]=1
PLAYERS+=("$id")
PLAYER_NAME[$id]="$name"
PLAYER_SERVER[$id]="$server"
done <<<"$result"
done
}
get_prize() {
selected=$((RANDOM % ${#PrizePacks[@]}))
"${PrizePacks[$selected]}"
}
award_prize() {
local server="$1"
local player="$2"
local command
prizeLog=""
for command in "${PrizeCommands[@]}"; do
command="${command//\{PLAYER\}/$player}"
send_rcon "$server" "$command" >/dev/null
prizeLog+=" $command"$'\n'
done
}
colour_logs() {
shopt -s nocasematch
while IFS= read -r line; do
line=$(sed -E 's|.*/ShopLog_([^/]+)_WP\.log:|\1: |' <<<"$line")
case $line in
# Raffle Logs
*RAFFLE\ INITIATED*) echo -e "${CLR_GOLD}$line${RESET}";;
*Active\ Servers*) echo -e "${CLR_AQUA}$line${RESET}";;
*Excluded\ player*) echo -e "${BOLD}${CLR_ORANGE}$line${RESET}";;
*Querying\ players*) echo -e "${CLR_AQUA}$line${RESET}";;
*Entry:*) echo -e "${CLR_AQUA}$line${RESET}";;
*▶\ Winner*) echo -e "${CLR_GREEN}$line${RESET}";;
*▶*) echo -e "${CLR_PURPLE}$line${RESET}";;
*Eligible\ Players*) echo -e "${BOLD}${CLR_AQUA}$line${RESET}";;
*\ \-\ WINNER:*) echo -e "${BOLD}${CLR_GREEN}$line${RESET}";;
*sent\ to*) echo -e "${BOLD}${CLR_GREEN}$line${RESET}";;
*RAFFLE\ COMPLETE*) echo -e "${CLR_GOLD}$line${RESET}";;
*) echo "$line" ;;
esac
done
shopt -u nocasematch
}
#######################
# COMMAND FUNCTIONS
#######################
cmd_version() {
echo -e "${CLR_TITLE}${BOLD}Scruffy Cluster Raffle v${version}${RESET}"
exit 0
}
usage() {
echo
echo -e "${CLR_TITLE}${BOLD}Scruffy Cluster Raffle v${version}${RESET}"
echo
echo -e "${BOLD}Description:${RESET}${CLR_TEXT}"
echo -e " CLI for running and maintaining raffles within the Scruffy Cluster"
echo -e " Raffle will first check for 5 or more players, if met, a raffle is run"
echo -e " Flags to force a raffle regardless are available."
echo
echo -e "${RESET}${BOLD}Usage:${RESET}${CLR_TEXT}"
echo -e " raffle ──── Run a regular raffle (Required: 5 Players) "
echo -e " raffle -f ──── Force a raffle, regardless of how many online players "
echo
echo -e " raffle -l ──── View the last 150 lines of the Raffle log "
echo -e " raffle -w ──── View the last 100 lines of the Winners Log "
echo -e " raffle -lw ──── View the last entry in Winners Log "
echo
echo -e " raffle -v ──── Check Raffle CLI Version "
echo
exit 1
}
#
# Raffle logs
#
cmd_log() {
echo
echo "Loading Live Raffle Log..."
echo -e "${CLR_AQUA}${BOLD} CTRL + C to Exit${RESET}"
sleep 1
tail -n 75 -F "$logFile" | colour_logs
}
cmd_winners() {
echo
echo "Loading Raffle Winners Log..."
sleep 1
tail -n 72 "$winnerLog" | colour_logs
}
cmd_last_winner() {
echo
echo -e "${CLR_GOLD}Last raffle winner${RESET}"
echo "───────────────────"
tail -n 12 "$winnerLog" | colour_logs
echo
}
####################
# MAIN CODE
###################
cmd_raffle() {
local mode="${1:-}"
# Log raffle output only
exec > >(tee >(sed -E 's/\x1B\[[0-9;]*[[:alpha:]]//g' >> "$logFile")) 2>&1
timestamp ""
timestamp "───── RAFFLE INITIATED ─────"
if [[ "$mode" != "-f" ]]; then
check_player_num
if [[ $OnlinePlayerCount -lt "${min_players}" ]]; then
timestamp "Less than ${min_players} players online"
timestamp "───── RAFFLE CANCELLED ─────" "$CLR_RED"
exit 0
fi
fi
get_active_servers
if ((${#ACTIVE_SERVERS[@]} == 0)); then
timestamp "No active servers online."
timestamp "───── RAFFLE CANCELLED ─────"
exit 0
fi
timestamp "Active Servers: $(
IFS=', '
echo "${ACTIVE_SERVERS[*]}"
)"
broadcast_all "SCRUFFY CLUSTER RAFFLE! - A winner will be drawn in 30 seconds!"
timestamp "Broadcasting Raffle Draw in 30 Seconds -> Active Servers"
timestamp "Waiting 30 seconds before draw..."
sleep 20
broadcast_all "10 seconds until the raffle draw!"
timestamp "Broadcasting Raffle Draw in 10 Seconds -> Active Servers"
sleep 7
chat_all "Drawing raffle..."
timestamp "Drawing raffle..."
chat_all "3..."
timestamp "3..."
sleep 1
chat_all "2..."
timestamp "2..."
sleep 1
chat_all "1..."
timestamp "1..."
sleep 1
chat_all "Drawing winner..."
timestamp "Drawing winner..."
get_online_players
timestamp ""
timestamp "Eligible Players: ${#PLAYERS[@]}" "$CLR_GREEN"
if ((${#PLAYERS[@]} == 0)); then
timestamp "No eligible players found."
chat_all "No eligible players were online for the raffle."
timestamp "───── RAFFLE CANCELLED ─────"
exit 0
fi
for id in "${PLAYERS[@]}"; do
timestamp "Entry: ${PLAYER_NAME[$id]} [$id] on ${PLAYER_SERVER[$id]}"
done
mapfile -t PLAYERS < <(printf '%s\n' "${PLAYERS[@]}" | shuf)
echo
echo -e "${CLR_PURPLE} ▶ PLAYER COUNT: ${CLR_GOLD}${#PLAYERS[@]}${RESET}"
echo
echo -e "${CLR_PURPLE}Shuffled player list:${RESET}"
for i in "${!PLAYERS[@]}"; do
playerID="${PLAYERS[$i]}"
echo "$i : ${PLAYER_NAME[$playerID]}"
done
echo
index=$((RANDOM % ${#PLAYERS[@]}))
echo -e "${CLR_PURPLE} ▶ Random index chosen: ${CLR_GREEN}${index}${RESET}"
winnerID="${PLAYERS[$index]}"
echo
echo "WinnerID: $winnerID"
echo -e " ▶ Winner: ${CLR_GREEN}${PLAYER_NAME[$winnerID]}${RESET}"
echo
winnerName="${PLAYER_NAME[$winnerID]}"
winnerServer="${PLAYER_SERVER[$winnerID]}"
[[ -z $winnerName ]] && {
echo "Winner selection failed." >&2
exit 1
}
timestamp ""
timestamp "WINNER: $winnerName [$winnerID]" "$CLR_GREEN"
timestamp ""
get_prize
broadcast_all "RAFFLE WINNER: $winnerName!"
chat_all "RAFFLE WINNER: $winnerName!"
timestamp "Waiting 10 seconds to congratulate..."
sleep 10
broadcast_all "Congratulations $winnerName! - You have won: $PrizeName"
chat_all "Congratulations $winnerName! You have won: $PrizeName"
timestamp "Congratulations $winnerName! You have won: $PrizeName" "$CLR_GOLD"
award_prize "$winnerServer" "$winnerID" "$CLR_GOLD"
timestamp "Prize $PrizeName sent to $winnerName" "$CLR_GREEN"
# Log all raffle details
winnerRecord=$(
cat <<EOF
────────────────────────────────────────────────────────────
Date : $(date '+%Y-%m-%d %H:%M:%S')
Winner : $winnerName
Player ID : $winnerID
Map : $winnerServer
Prize : $PrizeName
Prize(s):
$prizeLog
───────────────────────────────────────────────────────
EOF
)
printf '%s\n' "$winnerRecord" >>"$winnerLog"
timestamp "───── RAFFLE COMPLETE ─────"
}
####################
# COMMANDS
####################
case "${1:-}" in
"")
cmd_raffle
;;
-f)
cmd_raffle -f
;;
-v)
cmd_version
;;
-w)
cmd_winners
;;
-lw)
cmd_last_winner
;;
-l)
cmd_log
;;
-h)
usage
;;
*)
usage
;;
esac
