fix: discard rocket gift overflow between levels
This commit is contained in:
parent
a5e85e8b71
commit
88b20f9ca3
@ -222,14 +222,17 @@ public class RocketEnergyAggregator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理能量增加
|
// 处理能量增加;火箭满能时只消费到触发礼物,后续独立礼物留给下一级。
|
||||||
processRoomEnergyBatch(roomId, batch);
|
int processedCount = processRoomEnergyBatch(roomId, batch);
|
||||||
|
if (processedCount <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 处理成功后才删除Redis中的数据(使用 LTRIM)
|
// 处理成功后才删除Redis中的数据(使用 LTRIM)
|
||||||
redisTemplate.opsForList().trim(queueKey, batch.size(), -1);
|
redisTemplate.opsForList().trim(queueKey, processedCount, -1);
|
||||||
|
|
||||||
log.info("成功处理房间{}能量, 处理数量={}, 剩余={}",
|
log.info("成功处理房间{}能量, 处理数量={}, 剩余={}",
|
||||||
roomId, batch.size(), queueSize - batch.size());
|
roomId, processedCount, queueSize - processedCount);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -242,7 +245,7 @@ public class RocketEnergyAggregator {
|
|||||||
/**
|
/**
|
||||||
* 处理单个房间的能量批次
|
* 处理单个房间的能量批次
|
||||||
*/
|
*/
|
||||||
private void processRoomEnergyBatch(Long roomId, List<RocketEnergyAddCmd> batch) {
|
private int processRoomEnergyBatch(Long roomId, List<RocketEnergyAddCmd> batch) {
|
||||||
String riyadhToday = ZonedDateTimeAsiaRiyadhUtils.nowFormat("yyyy-MM-dd");
|
String riyadhToday = ZonedDateTimeAsiaRiyadhUtils.nowFormat("yyyy-MM-dd");
|
||||||
|
|
||||||
// 查询当前火箭状态
|
// 查询当前火箭状态
|
||||||
@ -264,7 +267,7 @@ public class RocketEnergyAggregator {
|
|||||||
// 校验状态
|
// 校验状态
|
||||||
if (!rocketStatus.canAddEnergy()) {
|
if (!rocketStatus.canAddEnergy()) {
|
||||||
log.warn("火箭不可充能, roomId={}, status={}", roomId, rocketStatus.getStatus());
|
log.warn("火箭不可充能, roomId={}, status={}", roomId, rocketStatus.getStatus());
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录增加前的状态
|
// 记录增加前的状态
|
||||||
@ -272,23 +275,38 @@ public class RocketEnergyAggregator {
|
|||||||
long maxEnergy = rocketStatus.getMaxEnergy();
|
long maxEnergy = rocketStatus.getMaxEnergy();
|
||||||
|
|
||||||
// 批量增加能量
|
// 批量增加能量
|
||||||
long totalEnergy = 0L;
|
long requestedEnergy = 0L;
|
||||||
|
long acceptedEnergy = 0L;
|
||||||
|
int processedCount = 0;
|
||||||
Long triggerUserId = null;
|
Long triggerUserId = null;
|
||||||
|
|
||||||
|
// 历史上可能存在“已满能但异步发射未完成”的状态;此时不消费新礼物。
|
||||||
|
if (rocketStatus.isFullEnergy()) {
|
||||||
|
Long retryTriggerUserId = batch.isEmpty() ? null : batch.get(0).getUserId();
|
||||||
|
rocketLaunchManager.launchAsync(roomId, retryTriggerUserId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (RocketEnergyAddCmd cmd : batch) {
|
for (RocketEnergyAddCmd cmd : batch) {
|
||||||
long beforeEnergy = rocketStatus.getCurrentEnergy();
|
long beforeEnergy = rocketStatus.getCurrentEnergy();
|
||||||
|
long giftEnergy = cmd.getGiftGoldValue();
|
||||||
|
|
||||||
// 增加能量
|
// 领域对象会把单笔礼物截断到当前火箭的剩余能量。
|
||||||
rocketStatus.addEnergy(cmd.getUserId(), cmd.getGiftGoldValue());
|
rocketStatus.addEnergy(cmd.getUserId(), giftEnergy);
|
||||||
totalEnergy += cmd.getGiftGoldValue();
|
requestedEnergy += giftEnergy;
|
||||||
|
processedCount++;
|
||||||
|
|
||||||
long afterEnergy = rocketStatus.getCurrentEnergy();
|
long afterEnergy = rocketStatus.getCurrentEnergy();
|
||||||
|
acceptedEnergy += afterEnergy - beforeEnergy;
|
||||||
|
|
||||||
// 记录触发满能量的用户
|
// 记录触发满能量的用户
|
||||||
if (beforeEnergy < maxEnergy && afterEnergy >= maxEnergy && triggerUserId == null) {
|
if (beforeEnergy < maxEnergy && afterEnergy >= maxEnergy && triggerUserId == null) {
|
||||||
triggerUserId = cmd.getUserId();
|
triggerUserId = cmd.getUserId();
|
||||||
log.info("找到触发升级的用户: userId={}, beforeEnergy={}, afterEnergy={}, maxEnergy={}",
|
long discardedEnergy = Math.max(0L, giftEnergy - (afterEnergy - beforeEnergy));
|
||||||
triggerUserId, beforeEnergy, afterEnergy, maxEnergy);
|
log.info("找到触发升级的用户: userId={}, beforeEnergy={}, afterEnergy={}, maxEnergy={}, 单笔溢出丢弃={}",
|
||||||
|
triggerUserId, beforeEnergy, afterEnergy, maxEnergy, discardedEnergy);
|
||||||
|
// 当前礼物之后的队列记录是独立送礼,留到下一级火箭再处理。
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,8 +318,8 @@ public class RocketEnergyAggregator {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("批量增加火箭能量: roomId={}, 批次数量={}, 总能量={}, 更新前={}, 更新后={}/{}",
|
log.info("批量增加火箭能量: roomId={}, 读取数量={}, 处理数量={}, 请求能量={}, 计入能量={}, 更新前={}, 更新后={}/{}",
|
||||||
roomId, batch.size(), totalEnergy, energyBeforeAdd,
|
roomId, batch.size(), processedCount, requestedEnergy, acceptedEnergy, energyBeforeAdd,
|
||||||
rocketStatus.getCurrentEnergy(), rocketStatus.getMaxEnergy());
|
rocketStatus.getCurrentEnergy(), rocketStatus.getMaxEnergy());
|
||||||
|
|
||||||
// 推送更新消息(节流)
|
// 推送更新消息(节流)
|
||||||
@ -320,6 +338,7 @@ public class RocketEnergyAggregator {
|
|||||||
// 异步触发发射
|
// 异步触发发射
|
||||||
rocketLaunchManager.launchAsync(roomId, triggerUserId);
|
rocketLaunchManager.launchAsync(roomId, triggerUserId);
|
||||||
}
|
}
|
||||||
|
return processedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -108,7 +108,13 @@ public class RocketStatus {
|
|||||||
* 增加能量
|
* 增加能量
|
||||||
*/
|
*/
|
||||||
public void addEnergy(Long userId,Long energyValue) {
|
public void addEnergy(Long userId,Long energyValue) {
|
||||||
this.currentEnergy += energyValue;
|
if (energyValue == null || energyValue <= 0 || this.currentEnergy >= this.maxEnergy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单笔礼物只补满当前火箭;超出当前档位的能量不进入下一级。
|
||||||
|
long acceptedEnergy = Math.min(energyValue, this.maxEnergy - this.currentEnergy);
|
||||||
|
this.currentEnergy += acceptedEnergy;
|
||||||
|
|
||||||
RocketContributor contributor = findContributor(userId);
|
RocketContributor contributor = findContributor(userId);
|
||||||
if (contributor == null) {
|
if (contributor == null) {
|
||||||
@ -119,46 +125,20 @@ public class RocketStatus {
|
|||||||
contributor.setFirstContributeTime(LocalDateTime.now());
|
contributor.setFirstContributeTime(LocalDateTime.now());
|
||||||
this.contributors.add(contributor);
|
this.contributors.add(contributor);
|
||||||
}
|
}
|
||||||
contributor.addEnergy(energyValue);
|
contributor.addEnergy(acceptedEnergy);
|
||||||
contributor.setLastContributeTime(LocalDateTime.now());
|
contributor.setLastContributeTime(LocalDateTime.now());
|
||||||
|
|
||||||
recalculateContributionRate();
|
recalculateContributionRate();
|
||||||
this.updatedAt = LocalDateTime.now();
|
this.updatedAt = LocalDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RocketStatus.java
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算能发射的最高等级
|
* 判断当前等级是否可以发射
|
||||||
* @return 能发射的等级,如果能量不足返回null
|
* @return 能发射的等级,如果能量不足返回null
|
||||||
*/
|
*/
|
||||||
public RocketLevel calculateLaunchLevel(RocketConfigGateway configGateway) {
|
public RocketLevel calculateLaunchLevel(RocketConfigGateway configGateway) {
|
||||||
long currentEnergy = this.currentEnergy;
|
// 发射等级只能是正在充能的当前等级,禁止单笔大额礼物直接跨级。
|
||||||
|
return isFullEnergy() ? this.level : null;
|
||||||
// 如果当前已经是最高级,不能再发射
|
|
||||||
if (this.level.isMaxLevel()) {
|
|
||||||
return this.level;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询所有启用的配置
|
|
||||||
List<RocketConfig> configs = configGateway.findAllEnabled();
|
|
||||||
if (configs == null || configs.isEmpty()) {
|
|
||||||
log.warn("未找到启用的火箭配置");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按等级从高到低排序
|
|
||||||
configs.sort((a, b) -> b.getLevel().compareTo(a.getLevel()));
|
|
||||||
|
|
||||||
// 从最高等级开始查找,找到能量满足发射条件的最高等级
|
|
||||||
for (RocketConfig config : configs) {
|
|
||||||
if (currentEnergy >= config.getMaxEnergy()) {
|
|
||||||
return RocketLevel.of(config.getLevel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,14 +167,11 @@ public class RocketStatus {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保留当前能量值
|
|
||||||
long preservedEnergy = this.currentEnergy;
|
|
||||||
|
|
||||||
// 升级到目标等级
|
// 升级到目标等级
|
||||||
RocketLevel oldLevel = this.level;
|
RocketLevel oldLevel = this.level;
|
||||||
this.level = targetLevel;
|
this.level = targetLevel;
|
||||||
this.maxEnergy = targetConfig.getMaxEnergy();
|
this.maxEnergy = targetConfig.getMaxEnergy();
|
||||||
this.currentEnergy = preservedEnergy; // 完全保留当前能量
|
this.currentEnergy = 0L;
|
||||||
this.status = RocketStatusEnum.CHARGING;
|
this.status = RocketStatusEnum.CHARGING;
|
||||||
|
|
||||||
// 清空贡献者(新一轮)
|
// 清空贡献者(新一轮)
|
||||||
@ -202,8 +179,8 @@ public class RocketStatus {
|
|||||||
this.launchTime = null;
|
this.launchTime = null;
|
||||||
this.claimExpireTime = null;
|
this.claimExpireTime = null;
|
||||||
|
|
||||||
log.info("火箭升级成功, {}级 -> {}级, 保留能量={}, 新目标={}",
|
log.info("火箭升级成功, {}级 -> {}级, 新等级能量从0开始, 新目标={}",
|
||||||
oldLevel.getLevel(), targetLevel.getLevel(), preservedEnergy, this.maxEnergy);
|
oldLevel.getLevel(), targetLevel.getLevel(), this.maxEnergy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user