Compare commits
7 Commits
2f45f23bd7
...
41305adb9d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41305adb9d | ||
|
|
f735b0a9a3 | ||
|
|
e0c4b72d4e | ||
|
|
93c39f77cf | ||
|
|
3a01a490ab | ||
|
|
1ac5e6c62d | ||
|
|
354f11150f |
@ -40,6 +40,7 @@ red-circle:
|
||||
secretId: ${LIKEI_TRTC_SECRET_ID}
|
||||
secretKey: ${LIKEI_TRTC_SECRET_KEY}
|
||||
endpoint: ${LIKEI_TRTC_ENDPOINT}
|
||||
region: ${LIKEI_TRTC_REGION:ap-singapore}
|
||||
sdkAppId: ${LIKEI_TRTC_SDK_APP_ID}
|
||||
tencet-im:
|
||||
appId: ${LIKEI_IM_APP_ID}
|
||||
|
||||
@ -7,4 +7,9 @@ task:
|
||||
base-url: ${TASK_CENTER_GO_URL:${LIKEI_GATEWAY_ROUTE_GO_URI:http://golang:2900}}
|
||||
internal-token: ${GAME_INTERNAL_CALLBACK_SECRET:}
|
||||
timeout-millis: ${TASK_CENTER_GO_TIMEOUT_MILLIS:3000}
|
||||
event:
|
||||
mq:
|
||||
enabled: ${TASK_CENTER_EVENT_MQ_ENABLED:false}
|
||||
topic: ${TASK_CENTER_EVENT_MQ_TOPIC:RC_DEFAULT_APP_ORDINARY}
|
||||
tag: ${TASK_CENTER_EVENT_MQ_TAG:task_center_event}
|
||||
|
||||
|
||||
@ -79,3 +79,8 @@ task:
|
||||
base-url: ${TASK_CENTER_GO_URL:${LIKEI_GATEWAY_ROUTE_GO_URI:http://golang:2900}}
|
||||
internal-token: ${GAME_INTERNAL_CALLBACK_SECRET:}
|
||||
timeout-millis: ${TASK_CENTER_GO_TIMEOUT_MILLIS:3000}
|
||||
event:
|
||||
mq:
|
||||
enabled: ${TASK_CENTER_EVENT_MQ_ENABLED:false}
|
||||
topic: ${TASK_CENTER_EVENT_MQ_TOPIC:RC_DEFAULT_APP_ORDINARY}
|
||||
tag: ${TASK_CENTER_EVENT_MQ_TAG:task_center_event}
|
||||
|
||||
@ -122,6 +122,11 @@ task:
|
||||
base-url: ${TASK_CENTER_GO_URL:${LIKEI_GATEWAY_ROUTE_GO_URI:http://golang:2900}}
|
||||
internal-token: ${GAME_INTERNAL_CALLBACK_SECRET:}
|
||||
timeout-millis: ${TASK_CENTER_GO_TIMEOUT_MILLIS:3000}
|
||||
event:
|
||||
mq:
|
||||
enabled: ${TASK_CENTER_EVENT_MQ_ENABLED:false}
|
||||
topic: ${TASK_CENTER_EVENT_MQ_TOPIC:RC_DEFAULT_APP_ORDINARY}
|
||||
tag: ${TASK_CENTER_EVENT_MQ_TAG:task_center_event}
|
||||
|
||||
voice-room:
|
||||
region-broadcast:
|
||||
|
||||
@ -18,3 +18,8 @@ task:
|
||||
base-url: ${TASK_CENTER_GO_URL:${LIKEI_GATEWAY_ROUTE_GO_URI:http://golang:2900}}
|
||||
internal-token: ${GAME_INTERNAL_CALLBACK_SECRET:}
|
||||
timeout-millis: ${TASK_CENTER_GO_TIMEOUT_MILLIS:3000}
|
||||
event:
|
||||
mq:
|
||||
enabled: ${TASK_CENTER_EVENT_MQ_ENABLED:false}
|
||||
topic: ${TASK_CENTER_EVENT_MQ_TOPIC:RC_DEFAULT_APP_ORDINARY}
|
||||
tag: ${TASK_CENTER_EVENT_MQ_TAG:task_center_event}
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
package com.red.circle.external.infra.config;
|
||||
|
||||
import com.red.circle.component.instant.msg.InstantMessageProperties;
|
||||
import com.red.circle.component.instant.msg.tencet.props.TrtcTencetProperties;
|
||||
import com.red.circle.component.instant.msg.tencet.service.endpoint.api.trtc.HyTrtcClient;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@Configuration
|
||||
public class TencentTrtcClientRegionConfiguration {
|
||||
|
||||
private static final String DEFAULT_TRTC_REGION = "ap-singapore";
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public HyTrtcClient regionAwareHyTrtcClient(
|
||||
InstantMessageProperties instantMessageProperties,
|
||||
@Value("${red-circle.instant-message.tencet-trtc.region:" + DEFAULT_TRTC_REGION + "}")
|
||||
String region) {
|
||||
TrtcTencetProperties trtcProperties = instantMessageProperties.getTencetTrtc();
|
||||
Credential credential = new Credential(
|
||||
trtcProperties.getSecretId(),
|
||||
trtcProperties.getSecretKey()
|
||||
);
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint(trtcProperties.getEndpoint());
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
String resolvedRegion = StringUtils.hasText(region) ? region.trim() : DEFAULT_TRTC_REGION;
|
||||
return new HyTrtcClient(credential, resolvedRegion, clientProfile);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
package com.red.circle.live.infra.client;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.red.circle.component.mq.MessageEvent;
|
||||
import com.red.circle.live.domain.constant.ActiveSecondConstant;
|
||||
import com.red.circle.mq.rocket.business.service.MessageSenderService;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
@ -14,6 +16,7 @@ import java.util.Objects;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -23,6 +26,8 @@ public class TaskCenterGoClient {
|
||||
|
||||
private static final String EVENT_TYPE_MIC_DURATION_SECONDS = "MIC_DURATION_SECONDS";
|
||||
|
||||
private final ObjectProvider<MessageSenderService> messageSenderServiceProvider;
|
||||
|
||||
@Value("${task.center.go.enabled:true}")
|
||||
private boolean enabled;
|
||||
|
||||
@ -35,6 +40,19 @@ public class TaskCenterGoClient {
|
||||
@Value("${task.center.go.timeout-millis:3000}")
|
||||
private Integer timeoutMillis;
|
||||
|
||||
@Value("${task.center.event.mq.enabled:false}")
|
||||
private boolean mqEnabled;
|
||||
|
||||
@Value("${task.center.event.mq.topic:RC_DEFAULT_APP_ORDINARY}")
|
||||
private String mqTopic;
|
||||
|
||||
@Value("${task.center.event.mq.tag:task_center_event}")
|
||||
private String mqTag;
|
||||
|
||||
public TaskCenterGoClient(ObjectProvider<MessageSenderService> messageSenderServiceProvider) {
|
||||
this.messageSenderServiceProvider = messageSenderServiceProvider;
|
||||
}
|
||||
|
||||
public void reportMicDuration(String sysOrigin,
|
||||
Long roomId,
|
||||
Integer micIndex,
|
||||
@ -81,6 +99,9 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
|
||||
private void reportEvent(TaskCenterEventRequest request) {
|
||||
if (mqEnabled) {
|
||||
publishMqEvent(request);
|
||||
}
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
@ -134,6 +155,24 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void publishMqEvent(TaskCenterEventRequest request) {
|
||||
try {
|
||||
MessageSenderService senderService = messageSenderServiceProvider.getIfAvailable();
|
||||
if (Objects.isNull(senderService)) {
|
||||
log.warn("Task center mq sender missing, skip event report. eventId={}", request.getEventId());
|
||||
return;
|
||||
}
|
||||
senderService.sendEventMessage(MessageEvent.builder()
|
||||
.consumeId(request.getEventId())
|
||||
.topicString(defaultIfBlank(mqTopic, "RC_DEFAULT_APP_ORDINARY"))
|
||||
.tag(defaultIfBlank(mqTag, "task_center_event"))
|
||||
.body(request)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.warn("Task center mq report error. eventId={}", request.getEventId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String readResponse(HttpURLConnection connection) {
|
||||
try (InputStream inputStream = connection.getErrorStream() != null
|
||||
? connection.getErrorStream()
|
||||
@ -166,6 +205,11 @@ public class TaskCenterGoClient {
|
||||
return value;
|
||||
}
|
||||
|
||||
private String defaultIfBlank(String value, String fallback) {
|
||||
String normalized = Objects.toString(value, "").trim();
|
||||
return normalized.isEmpty() ? fallback : normalized;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
private static class TaskCenterEventRequest {
|
||||
|
||||
@ -595,13 +595,14 @@ public class LiveMicrophoneGatewayImpl implements LiveMicrophoneGateway {
|
||||
List<LiveMicSettingSeat> liveMicSettingSeats = initMicSetting(roomId);
|
||||
if (CollectionUtils.isEmpty(liveMicSettingSeats)) {
|
||||
return CollectionUtils.newArrayList();
|
||||
}
|
||||
|
||||
Map<Integer, LiveMicrophone> liveMicrophoneMap = mapLiveMicrophone(roomId);
|
||||
log.info("在线取麦克风列表信息 -Map: {}", liveMicrophoneMap);
|
||||
return liveMicSettingSeats.stream().map(seat -> new LiveMicrophoneDTO()
|
||||
.setRoomId(roomId)
|
||||
.setMicIndex(seat.getMicIndex())
|
||||
}
|
||||
|
||||
Map<Integer, LiveMicrophone> liveMicrophoneMap = mapLiveMicrophone(roomId);
|
||||
log.debug("list live microphone map summary, roomId={}, micCount={}", roomId,
|
||||
liveMicrophoneMap.size());
|
||||
return liveMicSettingSeats.stream().map(seat -> new LiveMicrophoneDTO()
|
||||
.setRoomId(roomId)
|
||||
.setMicIndex(seat.getMicIndex())
|
||||
.setMicLock(seat.getMicLock())
|
||||
.setMicMute(seat.getMicMute())
|
||||
.setUser(liveMicInfraConvertor.toLiveMicUserDTO(
|
||||
@ -655,24 +656,26 @@ public class LiveMicrophoneGatewayImpl implements LiveMicrophoneGateway {
|
||||
public void initMicSetting(Long roomId, Integer micSize) {
|
||||
init(roomId, micSize);
|
||||
}
|
||||
|
||||
private Map<Integer, LiveMicrophone> mapLiveMicrophone(Long roomId) {
|
||||
List<LiveMicrophone> liveMicrophones = liveMicCacheService.listLiveMicrophone(roomId);
|
||||
log.info("在线取麦克风列表信息 -列表: {}", liveMicrophones);
|
||||
//获取房间用户心动值
|
||||
Map<Long, Long> liveHeartbeatMap = getLiveHeartbeatMap(liveHeartbeatClient.listLiveHeartbeat(roomId).getBody());
|
||||
if (CollectionUtils.isEmpty(liveMicrophones)) {
|
||||
|
||||
private Map<Integer, LiveMicrophone> mapLiveMicrophone(Long roomId) {
|
||||
List<LiveMicrophone> liveMicrophones = liveMicCacheService.listLiveMicrophone(roomId);
|
||||
log.debug("list live microphone cache summary, roomId={}, micCount={}", roomId,
|
||||
liveMicrophones.size());
|
||||
//获取房间用户心动值
|
||||
Map<Long, Long> liveHeartbeatMap = getLiveHeartbeatMap(liveHeartbeatClient.listLiveHeartbeat(roomId).getBody());
|
||||
if (CollectionUtils.isEmpty(liveMicrophones)) {
|
||||
return CollectionUtils.newHashMap();
|
||||
}
|
||||
|
||||
List<LiveMicUser> liveMicUsers = liveMicrophones.stream().map(LiveMicrophone::getUser).toList();
|
||||
List<Long> userIds = liveMicUsers.stream().map(LiveMicUser::getId).toList();
|
||||
updateLiveMicrophoneUserInfo(liveMicrophones, roomId, userIds);
|
||||
Map<Long, Long> cpUserIdMap = userCpClient.getCpUserIdByUserIds(userIds).getBody();
|
||||
log.info("用户ID集合={}, 结果集cpUserIdMap = {}", userIds, cpUserIdMap);
|
||||
return liveMicrophones.stream()
|
||||
.peek(liveMicrophone -> {
|
||||
LiveMicUser user = liveMicrophone.getUser();
|
||||
List<Long> userIds = liveMicUsers.stream().map(LiveMicUser::getId).toList();
|
||||
updateLiveMicrophoneUserInfo(liveMicrophones, roomId, userIds);
|
||||
Map<Long, Long> cpUserIdMap = userCpClient.getCpUserIdByUserIds(userIds).getBody();
|
||||
log.debug("list live microphone cp user summary, roomId={}, userCount={}, cpUserCount={}",
|
||||
roomId, userIds.size(), Objects.nonNull(cpUserIdMap) ? cpUserIdMap.size() : 0);
|
||||
return liveMicrophones.stream()
|
||||
.peek(liveMicrophone -> {
|
||||
LiveMicUser user = liveMicrophone.getUser();
|
||||
user.setHeartbeatVal(Objects.nonNull(liveHeartbeatMap.get(user.getId()))? liveHeartbeatMap.get(user.getId()):0L);
|
||||
user.setCpUserId(Objects.nonNull(cpUserIdMap.get(user.getId()))? cpUserIdMap.get(user.getId()):0L);
|
||||
liveMicrophone.setUser(user);
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.red.circle.order.app.common.task;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.red.circle.component.mq.MessageEvent;
|
||||
import com.red.circle.mq.rocket.business.service.MessageSenderService;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
@ -15,6 +17,7 @@ import java.util.Objects;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -24,6 +27,8 @@ public class TaskCenterGoClient {
|
||||
|
||||
private static final String EVENT_TYPE_RECHARGE_GOLD = "RECHARGE_GOLD";
|
||||
|
||||
private final ObjectProvider<MessageSenderService> messageSenderServiceProvider;
|
||||
|
||||
@Value("${task.center.go.enabled:true}")
|
||||
private boolean enabled;
|
||||
|
||||
@ -36,6 +41,19 @@ public class TaskCenterGoClient {
|
||||
@Value("${task.center.go.timeout-millis:3000}")
|
||||
private Integer timeoutMillis;
|
||||
|
||||
@Value("${task.center.event.mq.enabled:false}")
|
||||
private boolean mqEnabled;
|
||||
|
||||
@Value("${task.center.event.mq.topic:RC_DEFAULT_APP_ORDINARY}")
|
||||
private String mqTopic;
|
||||
|
||||
@Value("${task.center.event.mq.tag:task_center_event}")
|
||||
private String mqTag;
|
||||
|
||||
public TaskCenterGoClient(ObjectProvider<MessageSenderService> messageSenderServiceProvider) {
|
||||
this.messageSenderServiceProvider = messageSenderServiceProvider;
|
||||
}
|
||||
|
||||
public void reportRechargeGold(String sysOrigin,
|
||||
Long userId,
|
||||
Long purchaseHistoryId,
|
||||
@ -68,6 +86,9 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
|
||||
private void reportEvent(TaskCenterEventRequest request) {
|
||||
if (mqEnabled) {
|
||||
publishMqEvent(request);
|
||||
}
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
@ -109,6 +130,24 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void publishMqEvent(TaskCenterEventRequest request) {
|
||||
try {
|
||||
MessageSenderService senderService = messageSenderServiceProvider.getIfAvailable();
|
||||
if (Objects.isNull(senderService)) {
|
||||
log.warn("Task center mq sender missing, skip event report. eventId={}", request.getEventId());
|
||||
return;
|
||||
}
|
||||
senderService.sendEventMessage(MessageEvent.builder()
|
||||
.consumeId(request.getEventId())
|
||||
.topicString(defaultIfBlank(mqTopic, "RC_DEFAULT_APP_ORDINARY"))
|
||||
.tag(defaultIfBlank(mqTag, "task_center_event"))
|
||||
.body(request)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.warn("Task center mq report error. eventId={}", request.getEventId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String readResponse(HttpURLConnection connection) {
|
||||
try (InputStream inputStream = connection.getErrorStream() != null
|
||||
? connection.getErrorStream()
|
||||
@ -129,6 +168,11 @@ public class TaskCenterGoClient {
|
||||
return value;
|
||||
}
|
||||
|
||||
private String defaultIfBlank(String value, String fallback) {
|
||||
String normalized = Objects.toString(value, "").trim();
|
||||
return normalized.isEmpty() ? fallback : normalized;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
private static class TaskCenterEventRequest {
|
||||
|
||||
@ -51,12 +51,14 @@ import com.red.circle.tool.core.text.StringUtils;
|
||||
import com.red.circle.tool.crypto.SecurityUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -102,10 +104,12 @@ public class GameHkysRestController {
|
||||
return new HkysResponse<HkysUserProfileResponse>()
|
||||
.setErrorCode(HyksErrorEnum.PARAM_ERROR.getErrorCode());
|
||||
}
|
||||
String sign = SecurityUtils.md5(Stream.of(cmd.getGameId(), cmd.getUid(), cmd.getToken(), cmd.getRoomId(), gameHkysProperties.getSignKey()).filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining("")));
|
||||
if (!sign.equals(cmd.getSign())) {
|
||||
return new HkysResponse<HkysUserProfileResponse>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode());
|
||||
}
|
||||
if (!verifyLingxianUserInfoSign(cmd)) {
|
||||
log.warn("lingxian getUserInfo sign verify failed, uid={}, gameId={}, roomId={}, sysOrigin={}, tokenLength={}",
|
||||
cmd.getUid(), cmd.getGameId(), cmd.getRoomId(), resolveSysOriginQuietly(cmd.getToken()),
|
||||
cmd.getToken() == null ? 0 : cmd.getToken().length());
|
||||
return new HkysResponse<HkysUserProfileResponse>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode());
|
||||
}
|
||||
|
||||
HkysUserProfileQuery query = new HkysUserProfileQuery();
|
||||
query.setGameId(cmd.getGameId());
|
||||
@ -123,12 +127,12 @@ public class GameHkysRestController {
|
||||
|| Objects.isNull(cmd.getType()) || Objects.isNull(cmd.getCoin())) {
|
||||
return new HkysResponse<JSONObject>().setErrorCode(HyksErrorEnum.PARAM_ERROR.getErrorCode());
|
||||
}
|
||||
String sign = SecurityUtils.md5(Stream.of(cmd.getOrderId(), cmd.getGameId(), cmd.getRoundId(), cmd.getUid(),
|
||||
cmd.getCoin(), cmd.getType(), cmd.getToken(), cmd.getWinId(), cmd.getRoomId(), gameHkysProperties.getSignKey())
|
||||
.filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining("")));
|
||||
if (!sign.equals(cmd.getSign())) {
|
||||
return new HkysResponse<JSONObject>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode());
|
||||
}
|
||||
if (!verifyLingxianUpdateBalanceSign(cmd)) {
|
||||
log.warn("lingxian updateBalance sign verify failed, uid={}, gameId={}, orderId={}, roomId={}, sysOrigin={}, tokenLength={}",
|
||||
cmd.getUid(), cmd.getGameId(), cmd.getOrderId(), cmd.getRoomId(), resolveSysOriginQuietly(cmd.getToken()),
|
||||
cmd.getToken() == null ? 0 : cmd.getToken().length());
|
||||
return new HkysResponse<JSONObject>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode());
|
||||
}
|
||||
|
||||
HkysUserCoinUpdate param = new HkysUserCoinUpdate();
|
||||
param.setOrderId(cmd.getOrderId());
|
||||
@ -150,7 +154,7 @@ public class GameHkysRestController {
|
||||
//游玩一句游戏结束 每日任务 灵仙
|
||||
Long userId = DataTypeUtils.toLong(cmd.getUid());
|
||||
|
||||
String sysOrigin = UserCredential.parseToken(cmd.getToken()).getSysOrigin();
|
||||
String sysOrigin = parseSysOrigin(cmd.getToken());
|
||||
|
||||
BigDecimal cost = enumConfigCacheService
|
||||
.getValueBigDecimal(EnumConfigKey.GAME_BROADCAST_AMOUNT, sysOrigin) ;
|
||||
@ -223,6 +227,88 @@ public class GameHkysRestController {
|
||||
);
|
||||
}
|
||||
|
||||
private String resolveLingxianSignKey(String token) {
|
||||
List<String> keys = lingxianSignKeys(token);
|
||||
return keys.isEmpty() ? "" : keys.get(0);
|
||||
}
|
||||
|
||||
private boolean verifyLingxianUserInfoSign(GameLxwlUserInfoCmd cmd) {
|
||||
for (String token : lingxianTokenCandidates(cmd.getToken())) {
|
||||
for (String key : lingxianSignKeys(token)) {
|
||||
String sign = SecurityUtils.md5(Stream.of(cmd.getGameId(), cmd.getUid(), token, cmd.getRoomId(), key)
|
||||
.filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining("")));
|
||||
if (sign.equalsIgnoreCase(cmd.getSign())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean verifyLingxianUpdateBalanceSign(GameLxwlUpdateBalanceCmd cmd) {
|
||||
for (String token : lingxianTokenCandidates(cmd.getToken())) {
|
||||
for (String key : lingxianSignKeys(token)) {
|
||||
String sign = SecurityUtils.md5(Stream.of(cmd.getOrderId(), cmd.getGameId(), cmd.getRoundId(), cmd.getUid(),
|
||||
cmd.getCoin(), cmd.getType(), token, cmd.getWinId(), cmd.getRoomId(), key)
|
||||
.filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining("")));
|
||||
if (sign.equalsIgnoreCase(cmd.getSign())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<String> lingxianSignKeys(String token) {
|
||||
List<String> keys = new ArrayList<>();
|
||||
addIfNotBlank(keys, gameListConfigService.getActiveLingxianAppKey(resolveSysOriginQuietly(token)));
|
||||
addIfNotBlank(keys, gameHkysProperties.getSignKey());
|
||||
return keys;
|
||||
}
|
||||
|
||||
private List<String> lingxianTokenCandidates(String token) {
|
||||
List<String> tokens = new ArrayList<>();
|
||||
if (StringUtils.isBlank(token)) {
|
||||
tokens.add(null);
|
||||
return tokens;
|
||||
}
|
||||
addTokenCandidate(tokens, token);
|
||||
addTokenCandidate(tokens, SecurityUtils.urlDecode(token));
|
||||
return tokens;
|
||||
}
|
||||
|
||||
private void addTokenCandidate(List<String> tokens, String token) {
|
||||
if (StringUtils.isBlank(token)) {
|
||||
return;
|
||||
}
|
||||
addIfNotBlank(tokens, token);
|
||||
addIfNotBlank(tokens, trimTokenPadding(token));
|
||||
}
|
||||
|
||||
private String trimTokenPadding(String token) {
|
||||
return token == null ? "" : token.trim().replaceAll("=+$", "");
|
||||
}
|
||||
|
||||
private void addIfNotBlank(List<String> values, String value) {
|
||||
if (StringUtils.isBlank(value) || values.contains(value)) {
|
||||
return;
|
||||
}
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
private String resolveSysOriginQuietly(String token) {
|
||||
try {
|
||||
return parseSysOrigin(token);
|
||||
} catch (Exception e) {
|
||||
log.warn("resolve lingxian sysOrigin failed");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String parseSysOrigin(String token) {
|
||||
return UserCredential.parseToken(SecurityUtils.urlDecode(token)).getSysOrigin();
|
||||
}
|
||||
|
||||
private void reportTaskCenterGameEvents(String sysOrigin,
|
||||
Long userId,
|
||||
String provider,
|
||||
|
||||
@ -23,8 +23,9 @@ import org.springframework.stereotype.Service;
|
||||
@RequiredArgsConstructor
|
||||
public class RoomRegionFilterCommon {
|
||||
|
||||
// account 1001041, 1001545
|
||||
// account 1001035, 1001041, 1001545
|
||||
private static final Set<Long> ALL_REGION_ROOM_WHITELIST_USER_IDS = Set.of(
|
||||
2044358825183604738L,
|
||||
2044700023064686594L,
|
||||
2047206645188063233L
|
||||
);
|
||||
|
||||
@ -3,6 +3,8 @@ package com.red.circle.other.app.common.task;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.red.circle.component.mq.MessageEvent;
|
||||
import com.red.circle.mq.rocket.business.service.MessageSenderService;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
@ -11,6 +13,7 @@ import java.util.Objects;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -21,6 +24,8 @@ public class TaskCenterGoClient {
|
||||
private static final String EVENT_TYPE_GAME_CONSUME_GOLD = "GAME_CONSUME_GOLD";
|
||||
private static final String EVENT_TYPE_GIFT_CONSUME_GOLD = "GIFT_CONSUME_GOLD";
|
||||
|
||||
private final ObjectProvider<MessageSenderService> messageSenderServiceProvider;
|
||||
|
||||
@Value("${task.center.go.enabled:true}")
|
||||
private boolean enabled;
|
||||
|
||||
@ -33,6 +38,19 @@ public class TaskCenterGoClient {
|
||||
@Value("${task.center.go.timeout-millis:3000}")
|
||||
private Integer timeoutMillis;
|
||||
|
||||
@Value("${task.center.event.mq.enabled:false}")
|
||||
private boolean mqEnabled;
|
||||
|
||||
@Value("${task.center.event.mq.topic:RC_DEFAULT_APP_ORDINARY}")
|
||||
private String mqTopic;
|
||||
|
||||
@Value("${task.center.event.mq.tag:task_center_event}")
|
||||
private String mqTag;
|
||||
|
||||
public TaskCenterGoClient(ObjectProvider<MessageSenderService> messageSenderServiceProvider) {
|
||||
this.messageSenderServiceProvider = messageSenderServiceProvider;
|
||||
}
|
||||
|
||||
public void reportGameConsumeGold(String sysOrigin,
|
||||
Long userId,
|
||||
String provider,
|
||||
@ -101,6 +119,9 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
|
||||
private void reportEvent(TaskCenterEventRequest request) {
|
||||
if (mqEnabled) {
|
||||
publishMqEvent(request);
|
||||
}
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
@ -127,6 +148,24 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void publishMqEvent(TaskCenterEventRequest request) {
|
||||
try {
|
||||
MessageSenderService senderService = messageSenderServiceProvider.getIfAvailable();
|
||||
if (Objects.isNull(senderService)) {
|
||||
log.warn("Task center mq sender missing, skip event report. eventId={}", request.getEventId());
|
||||
return;
|
||||
}
|
||||
senderService.sendEventMessage(MessageEvent.builder()
|
||||
.consumeId(request.getEventId())
|
||||
.topicString(defaultIfBlank(mqTopic, "RC_DEFAULT_APP_ORDINARY"))
|
||||
.tag(defaultIfBlank(mqTag, "task_center_event"))
|
||||
.body(request)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.warn("Task center mq report error. eventId={}", request.getEventId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String trimRightSlash(String value) {
|
||||
while (value.endsWith("/")) {
|
||||
value = value.substring(0, value.length() - 1);
|
||||
@ -134,6 +173,11 @@ public class TaskCenterGoClient {
|
||||
return value;
|
||||
}
|
||||
|
||||
private String defaultIfBlank(String value, String fallback) {
|
||||
String normalized = Objects.toString(value, "").trim();
|
||||
return normalized.isEmpty() ? fallback : normalized;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
private static class TaskCenterEventRequest {
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.red.circle.other.app.common.room;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ -14,6 +16,16 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
class RoomRegionFilterCommonTest {
|
||||
|
||||
@Test
|
||||
void canViewAllRegions_shouldAllowConfiguredWhiteListUser() {
|
||||
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
|
||||
RoomRegionFilterCommon roomRegionFilterCommon = new RoomRegionFilterCommon(userRegionGateway);
|
||||
|
||||
assertTrue(roomRegionFilterCommon.canViewAllRegions(2044358825183604738L));
|
||||
assertFalse(roomRegionFilterCommon.canViewAllRegions(1001035L));
|
||||
assertFalse(roomRegionFilterCommon.canViewAllRegions(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterActiveVoiceRoomsByRegion_shouldKeepOnlyCurrentRegionRooms() {
|
||||
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
|
||||
|
||||
@ -46,10 +46,15 @@ public interface GameListConfigService extends BaseService<GameListConfig> {
|
||||
* 获取灵仙当前启用的配置档案.
|
||||
*/
|
||||
String getActiveLingxianProfile(String sysOrigin);
|
||||
|
||||
/**
|
||||
* 查询游戏信息
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取灵仙当前启用配置的 appKey.
|
||||
*/
|
||||
String getActiveLingxianAppKey(String sysOrigin);
|
||||
|
||||
/**
|
||||
* 查询游戏信息
|
||||
*/
|
||||
GameListConfig getByGameCode(String gameCode, String sysOrigin);
|
||||
|
||||
/**
|
||||
|
||||
@ -213,6 +213,27 @@ public class GameListConfigServiceImpl extends
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActiveLingxianAppKey(String sysOrigin) {
|
||||
if (StringUtils.isBlank(sysOrigin)) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
return Optional.ofNullable(jdbcTemplate.queryForObject("""
|
||||
SELECT app_key
|
||||
FROM lingxian_provider_config
|
||||
WHERE sys_origin = ?
|
||||
AND active = 1
|
||||
ORDER BY update_time DESC
|
||||
LIMIT 1
|
||||
""", String.class, sysOrigin))
|
||||
.map(String::trim)
|
||||
.orElse("");
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameListConfig getByGameCode(String gameCode, String sysOrigin) {
|
||||
return query()
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.red.circle.wallet.app.common.task;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.red.circle.component.mq.MessageEvent;
|
||||
import com.red.circle.mq.rocket.business.service.MessageSenderService;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
@ -15,6 +17,7 @@ import java.util.Objects;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -24,6 +27,8 @@ public class TaskCenterGoClient {
|
||||
|
||||
private static final String EVENT_TYPE_RECHARGE_GOLD = "RECHARGE_GOLD";
|
||||
|
||||
private final ObjectProvider<MessageSenderService> messageSenderServiceProvider;
|
||||
|
||||
@Value("${task.center.go.enabled:true}")
|
||||
private boolean enabled;
|
||||
|
||||
@ -36,6 +41,19 @@ public class TaskCenterGoClient {
|
||||
@Value("${task.center.go.timeout-millis:3000}")
|
||||
private Integer timeoutMillis;
|
||||
|
||||
@Value("${task.center.event.mq.enabled:false}")
|
||||
private boolean mqEnabled;
|
||||
|
||||
@Value("${task.center.event.mq.topic:RC_DEFAULT_APP_ORDINARY}")
|
||||
private String mqTopic;
|
||||
|
||||
@Value("${task.center.event.mq.tag:task_center_event}")
|
||||
private String mqTag;
|
||||
|
||||
public TaskCenterGoClient(ObjectProvider<MessageSenderService> messageSenderServiceProvider) {
|
||||
this.messageSenderServiceProvider = messageSenderServiceProvider;
|
||||
}
|
||||
|
||||
public void reportShippingAgentRechargeGold(String sysOrigin,
|
||||
Long userId,
|
||||
Long runningWaterId,
|
||||
@ -99,6 +117,9 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
|
||||
private void reportEvent(TaskCenterEventRequest request) {
|
||||
if (mqEnabled) {
|
||||
publishMqEvent(request);
|
||||
}
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
@ -140,6 +161,24 @@ public class TaskCenterGoClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void publishMqEvent(TaskCenterEventRequest request) {
|
||||
try {
|
||||
MessageSenderService senderService = messageSenderServiceProvider.getIfAvailable();
|
||||
if (Objects.isNull(senderService)) {
|
||||
log.warn("Task center mq sender missing, skip event report. eventId={}", request.getEventId());
|
||||
return;
|
||||
}
|
||||
senderService.sendEventMessage(MessageEvent.builder()
|
||||
.consumeId(request.getEventId())
|
||||
.topicString(defaultIfBlank(mqTopic, "RC_DEFAULT_APP_ORDINARY"))
|
||||
.tag(defaultIfBlank(mqTag, "task_center_event"))
|
||||
.body(request)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.warn("Task center mq report error. eventId={}", request.getEventId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String readResponse(HttpURLConnection connection) {
|
||||
try (InputStream inputStream = connection.getErrorStream() != null
|
||||
? connection.getErrorStream()
|
||||
@ -160,6 +199,11 @@ public class TaskCenterGoClient {
|
||||
return value;
|
||||
}
|
||||
|
||||
private String defaultIfBlank(String value, String fallback) {
|
||||
String normalized = Objects.toString(value, "").trim();
|
||||
return normalized.isEmpty() ? fallback : normalized;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
private static class TaskCenterEventRequest {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user