Skip to content

Commit 30ee4e4

Browse files
[sync] Update embedded LibCommand from standalone
1 parent b4d1831 commit 30ee4e4

20 files changed

Lines changed: 723 additions & 56 deletions

src/imperazim/command/Command.php

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use imperazim\command\constraint\PermissionConstraint;
1717
use imperazim\command\result\CommandResult;
1818
use imperazim\command\result\CommandFailure;
19+
use imperazim\command\HelpGenerator;
1920

2021
/**
2122
* Abstract base class for custom commands.
@@ -30,6 +31,15 @@ abstract class Command extends PMMPCommand {
3031
/** @var Plugin The plugin that owns this command */
3132
private readonly Plugin $plugin;
3233

34+
/** @var array Custom messages for command failures */
35+
private array $messages = [];
36+
37+
/** @var float|null Command cooldown in seconds */
38+
private ?float $cooldown = null;
39+
40+
/** @var array Last usage timestamps per sender */
41+
private static array $cooldowns = [];
42+
3343
/**
3444
* Constructor.
3545
*
@@ -44,6 +54,12 @@ public function __construct(Plugin $plugin) {
4454
$aliases = $config["aliases"] ?? [];
4555
$permission = $config["permission"] ?? DefaultPermissions::ROOT_USER;
4656

57+
// Store custom messages
58+
$this->messages = $config["messages"] ?? [];
59+
60+
// Store cooldown if provided
61+
$this->cooldown = $config["cooldown"] ?? null;
62+
4763
parent::__construct(
4864
$name,
4965
$description,
@@ -81,6 +97,96 @@ public function getPlugin(): Plugin {
8197
return $this->plugin;
8298
}
8399

100+
/**
101+
* Gets a custom message by key.
102+
*
103+
* @param string $key The message key
104+
* @param string $default Default message if key not found
105+
* @return string The message
106+
*/
107+
public function getMessage(string $key, string $default = ""): string {
108+
return $this->messages[$key] ?? $default;
109+
}
110+
111+
/**
112+
* Sets a custom message.
113+
*
114+
* @param string $key The message key
115+
* @param string $message The message text
116+
*/
117+
public function setMessage(string $key, string $message): void {
118+
$this->messages[$key] = $message;
119+
}
120+
121+
/**
122+
* Generates help text for this command.
123+
*
124+
* @param string $format The format style (detailed, compact, usage)
125+
* @return string The help text
126+
*/
127+
public function getHelp(string $format = "detailed"): string {
128+
return HelpGenerator::generate($this, $format);
129+
}
130+
131+
/**
132+
* Checks if sender is on cooldown.
133+
*
134+
* @param CommandSender $sender The sender to check
135+
* @return bool True if on cooldown
136+
*/
137+
private function isOnCooldown(CommandSender $sender): bool {
138+
if ($this->cooldown === null) {
139+
return false;
140+
}
141+
142+
$name = $sender->getName();
143+
$key = $this->getName() . ":" . $name;
144+
145+
if (!isset(self::$cooldowns[$key])) {
146+
return false;
147+
}
148+
149+
$elapsed = microtime(true) - self::$cooldowns[$key];
150+
return $elapsed < $this->cooldown;
151+
}
152+
153+
/**
154+
* Gets remaining cooldown time.
155+
*
156+
* @param CommandSender $sender The sender to check
157+
* @return float Remaining seconds
158+
*/
159+
private function getRemainingCooldown(CommandSender $sender): float {
160+
if ($this->cooldown === null) {
161+
return 0.0;
162+
}
163+
164+
$name = $sender->getName();
165+
$key = $this->getName() . ":" . $name;
166+
167+
if (!isset(self::$cooldowns[$key])) {
168+
return 0.0;
169+
}
170+
171+
$elapsed = microtime(true) - self::$cooldowns[$key];
172+
return max(0.0, $this->cooldown - $elapsed);
173+
}
174+
175+
/**
176+
* Updates sender's cooldown.
177+
*
178+
* @param CommandSender $sender The sender
179+
*/
180+
private function updateCooldown(CommandSender $sender): void {
181+
if ($this->cooldown === null) {
182+
return;
183+
}
184+
185+
$name = $sender->getName();
186+
$key = $this->getName() . ":" . $name;
187+
self::$cooldowns[$key] = microtime(true);
188+
}
189+
84190
/**
85191
* Executes the command.
86192
*
@@ -93,6 +199,16 @@ public function execute(
93199
string $label,
94200
array $rawArgs
95201
): void {
202+
// Check cooldown
203+
if ($this->isOnCooldown($sender)) {
204+
$remaining = $this->getRemainingCooldown($sender);
205+
$this->onFailure(
206+
new CommandFailure($sender, CommandFailure::COOLDOWN, [
207+
"remaining" => $remaining,
208+
])
209+
);
210+
return;
211+
}
96212
// Handle subcommands
97213
if (!empty($rawArgs)) {
98214
$key = strtolower(array_shift($rawArgs));
@@ -133,6 +249,9 @@ public function execute(
133249
$parsedArgs = $this->parseArguments($sender, $rawArgs);
134250

135251
try {
252+
// Update cooldown before execution
253+
$this->updateCooldown($sender);
254+
136255
// Execute command logic
137256
$this->onExecute(new CommandResult($sender, $parsedArgs, $label));
138257
} catch (\Throwable $e) {

0 commit comments

Comments
 (0)