New macro detection features (#7359)
* Adds battle config macro_detection_punishment to ban or jail characters. * Adds battle config macro_detection_punishment_time to adjust the duration of ban/jail for players who fail the captcha challenges. * Adds script command macro_detector which invokes the captcha challenge. * General cleanups to the jail functions to remove duplicate code. * General cleanups to the macro punishment calls to remove duplicate code. * Ending SC_JAILED will now properly remove the jail status rather than trying to reset the timer to 1 second resolving any possibility of players getting stuck. Thanks to @Lemongrass3110!
This commit is contained in:
parent
5a533a7a12
commit
ee2dcf816e
@ -158,3 +158,14 @@ macro_detection_retry: 3
|
|||||||
// Amount of time in milliseconds before the macro detection will fail and the user will be banned.
|
// Amount of time in milliseconds before the macro detection will fail and the user will be banned.
|
||||||
// Official: 60000
|
// Official: 60000
|
||||||
macro_detection_timeout: 60000
|
macro_detection_timeout: 60000
|
||||||
|
|
||||||
|
// Macro Detector punishment type
|
||||||
|
// 0 - Ban
|
||||||
|
// 1 - Jail
|
||||||
|
// Official: 0
|
||||||
|
macro_detection_punishment: 0
|
||||||
|
|
||||||
|
// Macro Detector punishment duration
|
||||||
|
// Amount of time in minutes that the punishment type is active for. Use 0 for infinite.
|
||||||
|
// Official: 0
|
||||||
|
macro_detection_punishment_time: 0
|
||||||
|
@ -6579,6 +6579,28 @@ Examples:
|
|||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
macro_detector({<account ID>});
|
||||||
|
macro_detector({"<character name>"});
|
||||||
|
|
||||||
|
This command will display the captcha UI challenge onto the invoking character or the given <account ID>/<character name>.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
// Use 'getareaunits' to gather an area of players to test.
|
||||||
|
// Build an int array of the account IDs.
|
||||||
|
.@num = getareaunits(BL_PC, "prontera", 150, 150, 160, 160, .@array[0]);
|
||||||
|
|
||||||
|
mes "The number of Players in Prontera in between 150x150 and 160x160 is " + .@num + " .";
|
||||||
|
mes "Players to challenge:";
|
||||||
|
freeloop(1); // If the list is too big
|
||||||
|
for(.@i = 0; .@i < getarraysize(.@array); .@i++) {
|
||||||
|
mes (.@i + 1) + " " + convertpcinfo(.@array[.@i], CPC_NAME);
|
||||||
|
macro_detector .@array[.@i];
|
||||||
|
}
|
||||||
|
freeloop(0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
==================================
|
==================================
|
||||||
|5.- Mob / NPC -related commands.|
|
|5.- Mob / NPC -related commands.|
|
||||||
==================================
|
==================================
|
||||||
|
@ -5218,8 +5218,7 @@ ACMD_FUNC(servertime)
|
|||||||
ACMD_FUNC(jail)
|
ACMD_FUNC(jail)
|
||||||
{
|
{
|
||||||
struct map_session_data *pl_sd;
|
struct map_session_data *pl_sd;
|
||||||
int x, y;
|
|
||||||
unsigned short m_index;
|
|
||||||
nullpo_retr(-1, sd);
|
nullpo_retr(-1, sd);
|
||||||
|
|
||||||
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
|
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
|
||||||
@ -5244,21 +5243,7 @@ ACMD_FUNC(jail)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(rnd() % 2) { //Jail Locations
|
pc_jail(*pl_sd);
|
||||||
case 0:
|
|
||||||
m_index = mapindex_name2id(MAP_JAIL);
|
|
||||||
x = 24;
|
|
||||||
y = 75;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
m_index = mapindex_name2id(MAP_JAIL);
|
|
||||||
x = 49;
|
|
||||||
y = 75;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Duration of INT_MAX to specify infinity.
|
|
||||||
sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000);
|
|
||||||
clif_displaymessage(pl_sd->fd, msg_txt(sd,117)); // GM has send you in jails.
|
clif_displaymessage(pl_sd->fd, msg_txt(sd,117)); // GM has send you in jails.
|
||||||
clif_displaymessage(fd, msg_txt(sd,118)); // Player warped in jails.
|
clif_displaymessage(fd, msg_txt(sd,118)); // Player warped in jails.
|
||||||
return 0;
|
return 0;
|
||||||
@ -5296,7 +5281,7 @@ ACMD_FUNC(unjail)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Reset jail time to 1 sec.
|
//Reset jail time to 1 sec.
|
||||||
sc_start(NULL,&pl_sd->bl,SC_JAILED,100,1,1000);
|
pc_jail(*pl_sd, 0);
|
||||||
clif_displaymessage(pl_sd->fd, msg_txt(sd,120)); // A GM has discharged you from jail.
|
clif_displaymessage(pl_sd->fd, msg_txt(sd,120)); // A GM has discharged you from jail.
|
||||||
clif_displaymessage(fd, msg_txt(sd,121)); // Player unjailed.
|
clif_displaymessage(fd, msg_txt(sd,121)); // Player unjailed.
|
||||||
return 0;
|
return 0;
|
||||||
@ -5305,8 +5290,8 @@ ACMD_FUNC(unjail)
|
|||||||
ACMD_FUNC(jailfor) {
|
ACMD_FUNC(jailfor) {
|
||||||
struct map_session_data *pl_sd = NULL;
|
struct map_session_data *pl_sd = NULL;
|
||||||
char * modif_p;
|
char * modif_p;
|
||||||
int jailtime = 0,x,y;
|
int jailtime = 0;
|
||||||
short m_index = 0;
|
|
||||||
nullpo_retr(-1, sd);
|
nullpo_retr(-1, sd);
|
||||||
|
|
||||||
memset(atcmd_output, '\0', sizeof(atcmd_output));
|
memset(atcmd_output, '\0', sizeof(atcmd_output));
|
||||||
@ -5363,19 +5348,8 @@ ACMD_FUNC(jailfor) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jail locations, add more as you wish.
|
pc_jail(*pl_sd, jailtime);
|
||||||
switch(rnd()%2) {
|
|
||||||
case 1: // Jail #1
|
|
||||||
m_index = mapindex_name2id(MAP_JAIL);
|
|
||||||
x = 49; y = 75;
|
|
||||||
break;
|
|
||||||
default: // Default Jail
|
|
||||||
m_index = mapindex_name2id(MAP_JAIL);
|
|
||||||
x = 24; y = 75;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status_change_timer).
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10271,6 +10271,8 @@ static const struct _battle_data {
|
|||||||
{ "break_mob_equip", &battle_config.break_mob_equip, 0, 0, 1, },
|
{ "break_mob_equip", &battle_config.break_mob_equip, 0, 0, 1, },
|
||||||
{ "macro_detection_retry", &battle_config.macro_detection_retry, 3, 1, INT_MAX, },
|
{ "macro_detection_retry", &battle_config.macro_detection_retry, 3, 1, INT_MAX, },
|
||||||
{ "macro_detection_timeout", &battle_config.macro_detection_timeout, 60000, 0, INT_MAX, },
|
{ "macro_detection_timeout", &battle_config.macro_detection_timeout, 60000, 0, INT_MAX, },
|
||||||
|
{ "macro_detection_punishment", &battle_config.macro_detection_punishment, 0, 0, 1, },
|
||||||
|
{ "macro_detection_punishment_time", &battle_config.macro_detection_punishment_time, 0, 0, INT_MAX, },
|
||||||
|
|
||||||
{ "feature.dynamicnpc_timeout", &battle_config.feature_dynamicnpc_timeout, 1000, 60000, INT_MAX, },
|
{ "feature.dynamicnpc_timeout", &battle_config.feature_dynamicnpc_timeout, 1000, 60000, INT_MAX, },
|
||||||
{ "feature.dynamicnpc_rangex", &battle_config.feature_dynamicnpc_rangex, 2, 0, INT_MAX, },
|
{ "feature.dynamicnpc_rangex", &battle_config.feature_dynamicnpc_rangex, 2, 0, INT_MAX, },
|
||||||
|
@ -714,6 +714,8 @@ struct Battle_Config
|
|||||||
int break_mob_equip;
|
int break_mob_equip;
|
||||||
int macro_detection_retry;
|
int macro_detection_retry;
|
||||||
int macro_detection_timeout;
|
int macro_detection_timeout;
|
||||||
|
int macro_detection_punishment;
|
||||||
|
int macro_detection_punishment_time;
|
||||||
|
|
||||||
int feature_dynamicnpc_timeout;
|
int feature_dynamicnpc_timeout;
|
||||||
int feature_dynamicnpc_rangex;
|
int feature_dynamicnpc_rangex;
|
||||||
|
@ -24776,7 +24776,7 @@ void clif_parse_macro_reporter_ack(int fd, map_session_data *sd) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pc_macro_reporter_process(*sd, *tsd);
|
pc_macro_reporter_process(*tsd, sd->status.account_id);
|
||||||
clif_macro_reporter_status(*sd, MCR_MONITORING);
|
clif_macro_reporter_status(*sd, MCR_MONITORING);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
102
src/map/pc.cpp
102
src/map/pc.cpp
@ -15235,6 +15235,76 @@ void pc_attendance_claim_reward( struct map_session_data* sd ){
|
|||||||
clif_attendence_response( sd, attendance_counter );
|
clif_attendence_response( sd, attendance_counter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a player to jail and determine the location to send in jail.
|
||||||
|
* @param sd: Player data
|
||||||
|
* @param duration: Duration in minutes (default INT_MAX = infinite)
|
||||||
|
*/
|
||||||
|
void pc_jail(map_session_data &sd, int32 duration) {
|
||||||
|
uint16 m_index = mapindex_name2id(MAP_JAIL);
|
||||||
|
int16 x, y;
|
||||||
|
|
||||||
|
switch (rnd() % 2) { // Jail Locations
|
||||||
|
case 0: // Jail #1
|
||||||
|
x = 49;
|
||||||
|
y = 75;
|
||||||
|
break;
|
||||||
|
default: // Default Jail
|
||||||
|
x = 24;
|
||||||
|
y = 75;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
duration = i32max(0, duration); // Can't be less than 0 seconds.
|
||||||
|
|
||||||
|
// If duration > 0 then triggered via jailfor which checks every minute.
|
||||||
|
// If duration == INT_MAX then triggered via jail for infinite duration.
|
||||||
|
// If duration == 0 then triggered via unjail and end status.
|
||||||
|
if (duration > 0)
|
||||||
|
sc_start4(nullptr, &sd.bl, SC_JAILED, 100, duration, m_index, x, y, 60000);
|
||||||
|
else
|
||||||
|
status_change_end(&sd.bl, SC_JAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the punishment type when failing macro checks.
|
||||||
|
* @param sd: Player data
|
||||||
|
* @param stype: Macro detection status type (for banning)
|
||||||
|
*/
|
||||||
|
static void pc_macro_punishment(map_session_data &sd, e_macro_detect_status stype) {
|
||||||
|
int32 duration = 0;
|
||||||
|
|
||||||
|
// Determine if there's a unique duration
|
||||||
|
if (battle_config.macro_detection_punishment_time > 0) {
|
||||||
|
char time[13];
|
||||||
|
|
||||||
|
safesnprintf(time, 13, "+%dnm", battle_config.macro_detection_punishment_time);
|
||||||
|
duration = static_cast<int32>(solve_time(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the timer
|
||||||
|
if (sd.macro_detect.timer != INVALID_TIMER)
|
||||||
|
delete_timer(sd.macro_detect.timer, pc_macro_detector_timeout);
|
||||||
|
|
||||||
|
// Clear the macro detect data
|
||||||
|
sd.macro_detect = {};
|
||||||
|
sd.macro_detect.timer = INVALID_TIMER;
|
||||||
|
|
||||||
|
// Unblock all actions for the player
|
||||||
|
sd.state.block_action &= ~PCBLOCK_ALL;
|
||||||
|
sd.state.block_action &= ~PCBLOCK_IMMUNE;
|
||||||
|
|
||||||
|
if (battle_config.macro_detection_punishment == 0) { // Ban
|
||||||
|
clif_macro_detector_status(sd, stype);
|
||||||
|
chrif_req_login_operation(sd.macro_detect.reporter_aid, sd.status.name, (duration == 0 ? CHRIF_OP_LOGIN_BLOCK : CHRIF_OP_LOGIN_BAN), duration, 0, 0);
|
||||||
|
} else { // Jail
|
||||||
|
// Send success to close the window without closing the client
|
||||||
|
clif_macro_detector_status(sd, MCD_GOOD);
|
||||||
|
|
||||||
|
pc_jail(sd, (duration == 0 ? INT_MAX : duration / 60));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a captcha image to memory via /macro_register.
|
* Save a captcha image to memory via /macro_register.
|
||||||
* @param sd: Player data
|
* @param sd: Player data
|
||||||
@ -15320,9 +15390,8 @@ TIMER_FUNC(pc_macro_detector_timeout) {
|
|||||||
sd->macro_detect.retry -= 1;
|
sd->macro_detect.retry -= 1;
|
||||||
|
|
||||||
if (sd->macro_detect.retry == 0) {
|
if (sd->macro_detect.retry == 0) {
|
||||||
// All attempts have been exhausted block the user
|
// All attempts have been exhausted, punish the user
|
||||||
clif_macro_detector_status(*sd, MCD_TIMEOUT);
|
pc_macro_punishment(*sd, MCD_TIMEOUT);
|
||||||
chrif_req_login_operation(sd->macro_detect.reporter_aid, sd->status.name, CHRIF_OP_LOGIN_BLOCK, 0, 0, 0);
|
|
||||||
} else {
|
} else {
|
||||||
// Update the client
|
// Update the client
|
||||||
clif_macro_detector_request_show(*sd);
|
clif_macro_detector_request_show(*sd);
|
||||||
@ -15373,10 +15442,9 @@ void pc_macro_detector_process_answer(map_session_data &sd, char captcha_answer[
|
|||||||
// Deduct an answering attempt
|
// Deduct an answering attempt
|
||||||
sd.macro_detect.retry -= 1;
|
sd.macro_detect.retry -= 1;
|
||||||
|
|
||||||
// All attempts have been exhausted block the user
|
// All attempts have been exhausted, punish the user
|
||||||
if (sd.macro_detect.retry <= 0) {
|
if (sd.macro_detect.retry <= 0) {
|
||||||
clif_macro_detector_status(sd, MCD_INCORRECT);
|
pc_macro_punishment(sd, MCD_INCORRECT);
|
||||||
chrif_req_login_operation(sd.macro_detect.reporter_aid, sd.status.name, CHRIF_OP_LOGIN_BLOCK, 0, 0, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15399,9 +15467,9 @@ void pc_macro_detector_disconnect(map_session_data &sd) {
|
|||||||
sd.macro_detect.timer = INVALID_TIMER;
|
sd.macro_detect.timer = INVALID_TIMER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the player disconnects before clearing the challenge the account is banned.
|
// If the player disconnects before clearing the challenge the player is punished.
|
||||||
if (sd.macro_detect.retry != 0)
|
if (sd.macro_detect.retry != 0)
|
||||||
chrif_req_login_operation(sd.macro_detect.reporter_aid, sd.status.name, CHRIF_OP_LOGIN_BLOCK, 0, 0, 0);
|
pc_macro_punishment(sd, MCD_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15438,10 +15506,10 @@ void pc_macro_reporter_area_select(map_session_data &sd, const int16 x, const in
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Send out captcha check to player.
|
* Send out captcha check to player.
|
||||||
* @param ssd: Source player data
|
* @param sd: Target player data
|
||||||
* @param tsd: Target player data
|
* @param reporter_account_id: Account ID of reporter
|
||||||
*/
|
*/
|
||||||
void pc_macro_reporter_process(map_session_data &ssd, map_session_data &tsd) {
|
void pc_macro_reporter_process(map_session_data &sd, int32 reporter_account_id) {
|
||||||
if (captcha_db.empty())
|
if (captcha_db.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -15449,18 +15517,18 @@ void pc_macro_reporter_process(map_session_data &ssd, map_session_data &tsd) {
|
|||||||
const std::shared_ptr<s_captcha_data> cd = captcha_db.random();
|
const std::shared_ptr<s_captcha_data> cd = captcha_db.random();
|
||||||
|
|
||||||
// Set macro detection data.
|
// Set macro detection data.
|
||||||
tsd.macro_detect.cd = cd;
|
sd.macro_detect.cd = cd;
|
||||||
tsd.macro_detect.reporter_aid = ssd.status.account_id;
|
sd.macro_detect.reporter_aid = reporter_account_id;
|
||||||
tsd.macro_detect.retry = battle_config.macro_detection_retry;
|
sd.macro_detect.retry = battle_config.macro_detection_retry;
|
||||||
|
|
||||||
// Block all actions for the target player.
|
// Block all actions for the target player.
|
||||||
tsd.state.block_action |= (PCBLOCK_ALL | PCBLOCK_IMMUNE);
|
sd.state.block_action |= (PCBLOCK_ALL | PCBLOCK_IMMUNE);
|
||||||
|
|
||||||
// Open macro detect client side.
|
// Open macro detect client side.
|
||||||
clif_macro_detector_request(tsd);
|
clif_macro_detector_request(sd);
|
||||||
|
|
||||||
// Start the timeout timer.
|
// Start the timeout timer.
|
||||||
tsd.macro_detect.timer = add_timer(gettick() + battle_config.macro_detection_timeout, pc_macro_detector_timeout, tsd.bl.id, 0);
|
sd.macro_detect.timer = add_timer(gettick() + battle_config.macro_detection_timeout, pc_macro_detector_timeout, sd.bl.id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1722,17 +1722,20 @@ bool pc_attendance_enabled();
|
|||||||
int32 pc_attendance_counter( struct map_session_data* sd );
|
int32 pc_attendance_counter( struct map_session_data* sd );
|
||||||
void pc_attendance_claim_reward( struct map_session_data* sd );
|
void pc_attendance_claim_reward( struct map_session_data* sd );
|
||||||
|
|
||||||
|
void pc_jail(map_session_data &sd, int32 duration = INT_MAX);
|
||||||
|
|
||||||
// Captcha Register
|
// Captcha Register
|
||||||
void pc_macro_captcha_register(map_session_data &sd, uint16 image_size, char captcha_answer[CAPTCHA_ANSWER_SIZE]);
|
void pc_macro_captcha_register(map_session_data &sd, uint16 image_size, char captcha_answer[CAPTCHA_ANSWER_SIZE]);
|
||||||
void pc_macro_captcha_register_upload(map_session_data & sd, uint16 upload_size, char *upload_data);
|
void pc_macro_captcha_register_upload(map_session_data & sd, uint16 upload_size, char *upload_data);
|
||||||
|
|
||||||
// Macro Detector
|
// Macro Detector
|
||||||
|
TIMER_FUNC(pc_macro_detector_timeout);
|
||||||
void pc_macro_detector_process_answer(map_session_data &sd, char captcha_answer[CAPTCHA_ANSWER_SIZE]);
|
void pc_macro_detector_process_answer(map_session_data &sd, char captcha_answer[CAPTCHA_ANSWER_SIZE]);
|
||||||
void pc_macro_detector_disconnect(map_session_data &sd);
|
void pc_macro_detector_disconnect(map_session_data &sd);
|
||||||
|
|
||||||
// Macro Reporter
|
// Macro Reporter
|
||||||
void pc_macro_reporter_area_select(map_session_data &sd, const int16 x, const int16 y, const int8 radius);
|
void pc_macro_reporter_area_select(map_session_data &sd, const int16 x, const int16 y, const int8 radius);
|
||||||
void pc_macro_reporter_process(map_session_data &ssd, map_session_data &tsd);
|
void pc_macro_reporter_process(map_session_data &sd, int32 reporter_account_id = -1);
|
||||||
|
|
||||||
#ifdef MAP_GENERATOR
|
#ifdef MAP_GENERATOR
|
||||||
void pc_reputation_generate();
|
void pc_reputation_generate();
|
||||||
|
@ -26829,6 +26829,25 @@ BUILDIN_FUNC(isdead) {
|
|||||||
return SCRIPT_CMD_SUCCESS;
|
return SCRIPT_CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUILDIN_FUNC(macro_detector) {
|
||||||
|
map_session_data *sd;
|
||||||
|
|
||||||
|
if (script_hasdata(st, 2) && script_isstring(st, 2)) { // Character Name
|
||||||
|
if (!script_nick2sd(2, sd)) {
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
} else { // Account ID
|
||||||
|
if (!script_accid2sd(2, sd)) {
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reporter Account ID as -1 for server.
|
||||||
|
pc_macro_reporter_process(*sd);
|
||||||
|
|
||||||
|
return SCRIPT_CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#include "../custom/script.inc"
|
#include "../custom/script.inc"
|
||||||
|
|
||||||
// declarations that were supposed to be exported from npc_chat.cpp
|
// declarations that were supposed to be exported from npc_chat.cpp
|
||||||
@ -27582,6 +27601,8 @@ struct script_function buildin_func[] = {
|
|||||||
BUILDIN_DEF(getfame, "?"),
|
BUILDIN_DEF(getfame, "?"),
|
||||||
BUILDIN_DEF(getfamerank, "?"),
|
BUILDIN_DEF(getfamerank, "?"),
|
||||||
BUILDIN_DEF(isdead, "?"),
|
BUILDIN_DEF(isdead, "?"),
|
||||||
|
BUILDIN_DEF(macro_detector, "?"),
|
||||||
|
|
||||||
#include "../custom/script_def.inc"
|
#include "../custom/script_def.inc"
|
||||||
|
|
||||||
{NULL,NULL,NULL},
|
{NULL,NULL,NULL},
|
||||||
|
@ -11257,7 +11257,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
|||||||
break;
|
break;
|
||||||
case SC_JAILED:
|
case SC_JAILED:
|
||||||
// Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
|
// Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
|
||||||
tick = val1>0?1000:250;
|
|
||||||
if (sd) {
|
if (sd) {
|
||||||
if (sd->mapindex != val2) {
|
if (sd->mapindex != val2) {
|
||||||
int pos = (bl->x&0xFFFF)|(bl->y<<16), // Current Coordinates
|
int pos = (bl->x&0xFFFF)|(bl->y<<16), // Current Coordinates
|
||||||
@ -13275,9 +13274,6 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SC_JAILED:
|
case SC_JAILED:
|
||||||
if(tid == INVALID_TIMER)
|
|
||||||
break;
|
|
||||||
// Natural expiration.
|
|
||||||
if(sd && sd->mapindex == sce->val2)
|
if(sd && sd->mapindex == sce->val2)
|
||||||
pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
|
pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
|
||||||
break; // Guess hes not in jail :P
|
break; // Guess hes not in jail :P
|
||||||
|
Loading…
x
Reference in New Issue
Block a user