Commit 3779e8d9 authored by nanahira's avatar nanahira

Merge branch 'master' into szonedl

parents 0de66e4b d15a8ef7
...@@ -34,24 +34,64 @@ void* LuaMemTracker::AllocThunk(void* ud, void* ptr, size_t osize, size_t nsize) ...@@ -34,24 +34,64 @@ void* LuaMemTracker::AllocThunk(void* ud, void* ptr, size_t osize, size_t nsize)
} }
void* LuaMemTracker::Alloc(void* ptr, size_t osize, size_t nsize) { void* LuaMemTracker::Alloc(void* ptr, size_t osize, size_t nsize) {
if (nsize == 0) { auto shrink = [&](size_t dec) {
// Clamp subtraction to avoid size_t underflow.
if (dec > total_allocated) {
total_allocated = 0;
} else {
total_allocated -= dec;
}
};
if (nsize == 0) { // free
if (ptr) { if (ptr) {
total_allocated -= osize; shrink(osize);
} }
return real_alloc(real_ud, ptr, osize, nsize); return real_alloc(real_ud, ptr, osize, nsize);
} else { }
size_t projected = total_allocated - osize + nsize;
if (limit && projected > limit) { // Unified path:
return nullptr; // over limit // - grow > 0: check limit using safe inequality, then alloc; on success add 'grow'
// - grow = 0: just alloc; accounting unchanged
// - shrink > 0: shrink first, alloc; on failure, rollback the shrink
auto do_alloc = [&](size_t grow_amount, size_t shrink_amount) -> void* {
if (grow_amount > 0 && limit) {
if (total_allocated >= limit || grow_amount > (limit - total_allocated)) {
return nullptr;
}
} }
void* newptr = real_alloc(real_ud, ptr, osize, nsize);
if (newptr) { auto result = real_alloc(real_ud, ptr, osize, nsize);
total_allocated = projected; if (result) {
if (shrink_amount > 0)
shrink(shrink_amount);
if (grow_amount > 0)
total_allocated += grow_amount;
#ifdef YGOPRO_LOG_LUA_MEMORY_SIZE #ifdef YGOPRO_LOG_LUA_MEMORY_SIZE
write_log(); write_log();
#endif #endif
} }
return newptr;
return result;
};
if (ptr) {
// realloc path: osize is the real old size
if (nsize > osize) {
// growth
size_t grow = nsize - osize;
return do_alloc(grow, 0);
} else if (nsize < osize) {
// shrink
size_t dec = osize - nsize;
return do_alloc(0, dec);
} else {
// no net change
return do_alloc(0, 0);
}
} else {
// malloc path: osize is a type tag; only count nsize
return do_alloc(nsize, 0);
} }
} }
......
...@@ -1846,6 +1846,8 @@ int32_t card::add_effect(effect* peffect) { ...@@ -1846,6 +1846,8 @@ int32_t card::add_effect(effect* peffect) {
return 0; return 0;
if (peffect->type & EFFECT_TYPES_TRIGGER_LIKE && is_continuous_event(peffect->code)) if (peffect->type & EFFECT_TYPES_TRIGGER_LIKE && is_continuous_event(peffect->code))
return 0; return 0;
if (peffect->type & EFFECT_TYPES_CHAIN_LINK && peffect->owner == pduel->game_field->temp_card)
return 0;
// the trigger effect in phase is "once per turn" by default // the trigger effect in phase is "once per turn" by default
if (peffect->get_code_type() == CODE_PHASE && peffect->code & (PHASE_DRAW | PHASE_STANDBY | PHASE_END) if (peffect->get_code_type() == CODE_PHASE && peffect->code & (PHASE_DRAW | PHASE_STANDBY | PHASE_END)
&& peffect->type & (EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F) && !peffect->is_flag(EFFECT_FLAG_COUNT_LIMIT)) { && peffect->type & (EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F) && !peffect->is_flag(EFFECT_FLAG_COUNT_LIMIT)) {
......
...@@ -1207,6 +1207,8 @@ void field::add_effect(effect* peffect, uint8_t owner_player) { ...@@ -1207,6 +1207,8 @@ void field::add_effect(effect* peffect, uint8_t owner_player) {
return; return;
if (effects.indexer.find(peffect) != effects.indexer.end()) if (effects.indexer.find(peffect) != effects.indexer.end())
return; return;
if (peffect->type & EFFECT_TYPES_CHAIN_LINK && peffect->owner == temp_card)
return;
effect_container::iterator it; effect_container::iterator it;
if (!(peffect->type & EFFECT_TYPE_ACTIONS)) { if (!(peffect->type & EFFECT_TYPE_ACTIONS)) {
it = effects.aura_effect.emplace(peffect->code, peffect); it = effects.aura_effect.emplace(peffect->code, peffect);
......
...@@ -92,7 +92,7 @@ public: ...@@ -92,7 +92,7 @@ public:
#define COROUTINE_ERROR 3 #define COROUTINE_ERROR 3
#ifndef YGOPRO_LUA_MEMORY_SIZE #ifndef YGOPRO_LUA_MEMORY_SIZE
#define YGOPRO_LUA_MEMORY_SIZE 134217728 // 128 MB #define YGOPRO_LUA_MEMORY_SIZE 0 // disable memory limit by default
#endif #endif
#endif /* INTERPRETER_H_ */ #endif /* INTERPRETER_H_ */
...@@ -193,6 +193,15 @@ int32_t scriptlib::card_get_removed_overlay_count(lua_State *L) { ...@@ -193,6 +193,15 @@ int32_t scriptlib::card_get_removed_overlay_count(lua_State *L) {
lua_pushinteger(L, pcard->removed_overlay_count); lua_pushinteger(L, pcard->removed_overlay_count);
return 1; return 1;
} }
int32_t scriptlib::card_check_spsummon_once(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
auto playerid = (int32_t)lua_tointeger(L, 2);
auto pduel = pcard->pduel;
lua_pushboolean(L, pduel->game_field->check_spsummon_once(pcard, playerid));
return 1;
}
int32_t scriptlib::card_get_code(lua_State *L) { int32_t scriptlib::card_get_code(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
...@@ -3677,6 +3686,7 @@ static const struct luaL_Reg cardlib[] = { ...@@ -3677,6 +3686,7 @@ static const struct luaL_Reg cardlib[] = {
{ "GetRemovedOverlayCount", scriptlib::card_get_removed_overlay_count }, { "GetRemovedOverlayCount", scriptlib::card_get_removed_overlay_count },
{ "IsAbleToDecreaseAttackAsCost", scriptlib::card_is_able_to_decrease_attack_as_cost }, { "IsAbleToDecreaseAttackAsCost", scriptlib::card_is_able_to_decrease_attack_as_cost },
{ "IsAbleToDecreaseDefenseAsCost", scriptlib::card_is_able_to_decrease_defense_as_cost }, { "IsAbleToDecreaseDefenseAsCost", scriptlib::card_is_able_to_decrease_defense_as_cost },
{ "CheckSPSummonOnce", scriptlib::card_check_spsummon_once },
{ "GetCode", scriptlib::card_get_code }, { "GetCode", scriptlib::card_get_code },
{ "GetOriginalCode", scriptlib::card_get_origin_code }, { "GetOriginalCode", scriptlib::card_get_origin_code },
......
...@@ -378,6 +378,20 @@ int32_t scriptlib::duel_enable_global_flag(lua_State *L) { ...@@ -378,6 +378,20 @@ int32_t scriptlib::duel_enable_global_flag(lua_State *L) {
return 0; return 0;
} }
int32_t scriptlib::duel_is_global_flag(lua_State *L) {
check_param_count(L, 1);
int32_t flag = (int32_t)lua_tointeger(L, 1);
duel* pduel = interpreter::get_duel_info(L);
if((pduel->game_field->core.global_flag & flag) == flag) {
lua_pushboolean(L, 1); // true
} else {
lua_pushboolean(L, 0); // false
}
return 1; // 返回一个结果值
}
int32_t scriptlib::duel_get_lp(lua_State *L) { int32_t scriptlib::duel_get_lp(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
int32_t p = (int32_t)lua_tointeger(L, 1); int32_t p = (int32_t)lua_tointeger(L, 1);
...@@ -5336,6 +5350,7 @@ static const struct luaL_Reg duellib[] = { ...@@ -5336,6 +5350,7 @@ static const struct luaL_Reg duellib[] = {
{ "SetRegistry", scriptlib::duel_set_registry }, { "SetRegistry", scriptlib::duel_set_registry },
{ "GetRegistry", scriptlib::duel_get_registry }, { "GetRegistry", scriptlib::duel_get_registry },
{ "ClearRegistry", scriptlib::duel_clear_registry }, { "ClearRegistry", scriptlib::duel_clear_registry },
{ "IsGlobalFlag", scriptlib::duel_is_global_flag },
{ "EnableGlobalFlag", scriptlib::duel_enable_global_flag }, { "EnableGlobalFlag", scriptlib::duel_enable_global_flag },
{ "GetLP", scriptlib::duel_get_lp }, { "GetLP", scriptlib::duel_get_lp },
......
...@@ -24,7 +24,7 @@ int32_t field::negate_chain(uint8_t chaincount) { ...@@ -24,7 +24,7 @@ int32_t field::negate_chain(uint8_t chaincount) {
pchain.flag |= CHAIN_DISABLE_ACTIVATE; pchain.flag |= CHAIN_DISABLE_ACTIVATE;
pchain.disable_reason = core.reason_effect; pchain.disable_reason = core.reason_effect;
pchain.disable_player = core.reason_player; pchain.disable_player = core.reason_player;
if((pchain.triggering_effect->type & EFFECT_TYPE_ACTIVATE) && (phandler->current.location == LOCATION_SZONE)) { if((pchain.triggering_effect->type & EFFECT_TYPE_ACTIVATE) && phandler->is_has_relation(pchain) && (phandler->current.location == LOCATION_SZONE)) {
phandler->set_status(STATUS_LEAVE_CONFIRMED, TRUE); phandler->set_status(STATUS_LEAVE_CONFIRMED, TRUE);
phandler->set_status(STATUS_ACTIVATE_DISABLED, TRUE); phandler->set_status(STATUS_ACTIVATE_DISABLED, TRUE);
} }
......
...@@ -37,6 +37,7 @@ public: ...@@ -37,6 +37,7 @@ public:
static int32_t card_get_origin_link_marker(lua_State *L); static int32_t card_get_origin_link_marker(lua_State *L);
static int32_t card_is_xyz_summonable_by_rose(lua_State *L); static int32_t card_is_xyz_summonable_by_rose(lua_State *L);
static int32_t card_get_removed_overlay_count(lua_State *L); static int32_t card_get_removed_overlay_count(lua_State *L);
static int32_t card_check_spsummon_once(lua_State *L);
static int32_t effect_set_owner(lua_State *L); static int32_t effect_set_owner(lua_State *L);
static int32_t effect_get_count_limit(lua_State *L); static int32_t effect_get_count_limit(lua_State *L);
static int32_t duel_get_master_rule(lua_State *L); static int32_t duel_get_master_rule(lua_State *L);
...@@ -57,6 +58,7 @@ public: ...@@ -57,6 +58,7 @@ public:
static int32_t duel_set_registry(lua_State *L); static int32_t duel_set_registry(lua_State *L);
static int32_t duel_get_registry(lua_State *L); static int32_t duel_get_registry(lua_State *L);
static int32_t duel_clear_registry(lua_State *L); static int32_t duel_clear_registry(lua_State *L);
static int32_t duel_is_global_flag(lua_State *L);
//card lib //card lib
static int32_t card_get_code(lua_State *L); static int32_t card_get_code(lua_State *L);
static int32_t card_get_origin_code(lua_State *L); static int32_t card_get_origin_code(lua_State *L);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment