新增 JoyPlay 游戏支持

This commit is contained in:
edwinQQQ
2025-05-08 17:10:54 +08:00
parent 07ebee2fc1
commit ffdfa121f9
5 changed files with 251 additions and 59 deletions

View File

@@ -77,6 +77,9 @@ typedef NS_ENUM(NSInteger, ActivityType) {
///商⼾渠道BAISHUN 提供,商⼾后台可查看)
@property(nonatomic,copy) NSString *appChannel;
/// JOYPLAY 渠道游戏使用
@property (nonatomic, copy) NSString *appKey;
@property (nonatomic, assign) NSInteger gameId;
@end
NS_ASSUME_NONNULL_END

View File

@@ -10,7 +10,7 @@
@implementation ActivityInfoModel
- (void)setRuleValue:(NSString *)ruleValue{
_ruleValue = ruleValue;
id data = [_ruleValue mj_JSONObject];
id data = [_ruleValue mj_JSONObject];
if([data isKindOfClass:[NSDictionary class]]){
NSDictionary *dic = (NSDictionary *)data;
if(dic[@"RESERVE"]!=nil){

View File

@@ -228,11 +228,9 @@
[resultIndexs addObject:@(value)];
sendInfo.resultIndexes = [resultIndexs copy];
}
}else {
sendInfo.resultIndexes = [[self randomArray:(short)faceInfo.resultStartPos to:(short)faceInfo.resultEndPos count:(short)faceInfo.resultCount] mutableCopy];
}
}
NSMutableArray *faceRecieveInfos = [NSMutableArray array];
sendInfo.nick = self.userInfo.nick;

View File

@@ -326,7 +326,9 @@
}
- (void)handleActivityInfo:(ActivityInfoModel *)model {
if ([model.code isEqualToString:@"LUCKY_BAG"]) {
if ([model.code isEqualToString:@"JOYPLAY"]) {
[self clickGameVC:model];
} else if ([model.code isEqualToString:@"LUCKY_BAG"]) {
if ([[self.hostDelegate getUserInfo] isRechargeUser]) {
[XNDJTDDLoadingTool showErrorWithMessage:YMLocalizedString(@"1.0.37_text_52")];
return;
@@ -385,7 +387,7 @@
}
-(void)clickGameVC:(ActivityInfoModel *)model{
if ([self.hostDelegate isKindOfClass:[XPRoomViewController class]]){
MSRoomGameWebVC *vc = [[MSRoomGameWebVC alloc]initWithDelegate:self.hostDelegate gameModel:model];
MSRoomGameWebVC *vc = [[MSRoomGameWebVC alloc] initWithDelegate:self.hostDelegate gameModel:model];
vc.view.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
XPRoomViewController *roomVC = (XPRoomViewController *)self.hostDelegate;
[roomVC addChildViewController:vc];

View File

@@ -40,11 +40,22 @@
@end
typedef NS_ENUM(NSInteger, MSGameType) {
MSGameTypeBaiShun, //
MSGameTypeJoyPlay, // JoyPlay
MSGameTypeCC // CC
};
NSString * const kMSGetConfig = @"getConfig";
NSString * const kMSDestroy = @"destroy";
NSString * const kMSGameRecharge = @"gameRecharge";
NSString * const kMSGameLoaded = @"gameLoaded";
NSString * const kJPRecharge = @"recharge";
NSString * const kJPClickRecharge = @"clickRecharge";
NSString * const kJPClose = @"newTppClose";
@interface MSRoomGameWebVC () <WKNavigationDelegate, WKScriptMessageHandler,WKUIDelegate>
@property (strong, nonatomic) WKWebView *webView;
@@ -53,19 +64,59 @@ NSString * const kMSGameLoaded = @"gameLoaded";
@property (nonatomic,weak) id<RoomHostDelegate> hostDelegate;
@property(nonatomic,strong) ActivityInfoModel *gameModel;
@property(nonatomic,strong) UIButton *backBtn;
@property (nonatomic, assign) BOOL isBaiShun;
@property (nonatomic, assign) MSGameType gameType;
@property (nonatomic, assign) BOOL isCharing;
@property (nonatomic, strong) NSURLRequest *lastRequest;
@property (nonatomic, assign) NSInteger retryCount;
@property (nonatomic, strong) NSTimer *loadingTimer;
@end
@implementation MSRoomGameWebVC
- (void)dealloc {
[self cleanupWebView];
[self.loadingTimer invalidate];
self.loadingTimer = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)cleanupWebView {
if (_webView) {
[_webView stopLoading];
_webView.navigationDelegate = nil;
_webView.UIDelegate = nil;
[_webView removeFromSuperview];
_webView = nil;
}
if (_ms_userContentController) {
[_ms_userContentController removeScriptMessageHandlerForName:kMSGetConfig];
[_ms_userContentController removeScriptMessageHandlerForName:kMSDestroy];
[_ms_userContentController removeScriptMessageHandlerForName:kMSGameRecharge];
[_ms_userContentController removeScriptMessageHandlerForName:kMSGameLoaded];
[_ms_userContentController removeScriptMessageHandlerForName:@"closeGame"];
[_ms_userContentController removeScriptMessageHandlerForName:@"pay"];
[_ms_userContentController removeScriptMessageHandlerForName:kJPClose];
[_ms_userContentController removeScriptMessageHandlerForName:kJPRecharge];
[_ms_userContentController removeScriptMessageHandlerForName:kJPClickRecharge];
_ms_userContentController = nil;
}
}
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate gameModel:(ActivityInfoModel *)gameModel
{
self = [super init];
if (self) {
self.hostDelegate = delegate;
self.gameModel = gameModel;
self.isBaiShun = [gameModel.code.uppercaseString isEqualToString:@"BAISHUN"];
NSString *upperCode = gameModel.code.uppercaseString;
if ([upperCode isEqualToString:@"BAISHUN"]) {
self.gameType = MSGameTypeBaiShun;
} else if ([upperCode isEqualToString:@"JOYPLAY"]) {
self.gameType = MSGameTypeJoyPlay;
} else {
self.gameType = MSGameTypeCC;
}
}
return self;
}
@@ -76,13 +127,52 @@ NSString * const kMSGameLoaded = @"gameLoaded";
[super viewDidLoad];
[self installUI];
[self setupBackButton];
#if DEBUG
// [self setupLoadingTimer];
#endif
[self setupNotifications];
[self showLoading];
}
- (void)setupLoadingTimer {
self.loadingTimer = [NSTimer scheduledTimerWithTimeInterval:15.0
target:self
selector:@selector(handleLoadingTimeout)
userInfo:nil
repeats:NO];
}
- (void)setupNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleApplicationDidBecomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleApplicationWillResignActive)
name:UIApplicationWillResignActiveNotification
object:nil];
}
- (void)handleLoadingTimeout {
[self hideHUD];
[XNDJTDDLoadingTool showErrorWithMessage:@"加载超时,请检查网络后重试"];
}
- (void)handleApplicationDidBecomeActive {
if (self.webView && !self.webView.isLoading) {
[self.webView reload];
}
}
- (void)handleApplicationWillResignActive {
[self.webView evaluateJavaScript:@"if(typeof(onAppPause) === 'function') { onAppPause(); }" completionHandler:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!self.isBaiShun &&
if (self.gameType != MSGameTypeBaiShun &&
self.isCharing) {
self.isCharing = NO;
[self updateCoin];
@@ -90,14 +180,23 @@ NSString * const kMSGameLoaded = @"gameLoaded";
}
- (void)setupBackButton {
if (self.gameType == MSGameTypeJoyPlay && self.gameModel.showType == ActivityShowType_Full) {
return;
}
self.backBtn = [UIButton new];
[self.view addSubview:self.backBtn];
self.backBtn.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
[self.backBtn addTarget:self action:@selector(backBtnAction) forControlEvents:UIControlEventTouchUpInside];
}
-(void)installUI{
- (void)installUI {
self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.4];
[self setupWebViewConfiguration];
[self setupWebViewConfiguration];
[self loadGameContent];
}
- (void)setupWebViewConfiguration {
MSWeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[MSWeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
_ms_userContentController = [[WKUserContentController alloc] init];
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSGetConfig];
@@ -109,9 +208,18 @@ NSString * const kMSGameLoaded = @"gameLoaded";
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:@"closeGame"];
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:@"pay"];
/// JOYPLAY
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate
name:kJPClose];
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate
name:kJPRecharge];
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate
name:kJPClickRecharge];
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
config.allowsInlineMediaPlayback = YES;
config.mediaTypesRequiringUserActionForPlayback = NO;
[config setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
//⼿,
config.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
@@ -123,7 +231,7 @@ NSString * const kMSGameLoaded = @"gameLoaded";
config.userContentController = _ms_userContentController;
CGRect frame = CGRectZero;
if (self.isBaiShun) {
if (self.gameType == MSGameTypeBaiShun) {
frame = CGRectMake(0,0,
KScreenWidth, KScreenHeight);
} else {
@@ -149,43 +257,85 @@ NSString * const kMSGameLoaded = @"gameLoaded";
self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
[self.view addSubview:self.webView];
}
- (void)loadGameContent {
NSString *h5Url = self.gameModel.skipContent;
NSURL *url = [self handleGameURL:h5Url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
if (!url) {
[self hideHUD];
[XNDJTDDLoadingTool showErrorWithMessage:@"游戏链接无效"];
return;
}
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:15.0];
self.lastRequest = request;
[self.webView loadRequest:request];
}
- (BOOL)isValidGameURL:(NSString *)urlString {
if (!urlString || ![urlString isKindOfClass:[NSString class]] || urlString.length == 0) {
return NO;
}
NSURL *url = [NSURL URLWithString:urlString];
return (url && url.scheme && url.host);
}
- (NSURL *)handleGameURL:(NSString *)url {
if (self.isBaiShun) {
return [NSURL URLWithString:url];
} else {
url = [url stringByAppendingFormat:@"&uid=%@", [AccountInfoStorage instance].getUid];
url = [url stringByAppendingFormat:@"&token=%@", self.gameModel.gameModel.code];
if (isMSEN()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"en-US"];
} else if (isMSTR()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"tr-TR"];
} else if (isMSZH()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"zh-TW"];
} else if (isMSRTL()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"ar-EG"];
}
url = [url stringByAppendingFormat:@"&roomid=%ld", (long)self.hostDelegate.getRoomInfo.uid];
return [NSURL URLWithString:url];
if (![self isValidGameURL:url]) {
return nil;
}
return nil;
switch (self.gameType) {
case MSGameTypeBaiShun:
return [NSURL URLWithString:url];
case MSGameTypeJoyPlay:
url = [url stringByAppendingFormat:@"?gameId=%@", @(self.gameModel.gameModel.gameId)];
url = [url stringByAppendingFormat:@"&appKey=%@",
self.gameModel.gameModel.appKey];
url = [url stringByAppendingFormat:@"&mini=%@", @(self.gameModel.showType == ActivityShowType_Half ? 1 : 0)];
if (self.gameModel.showType == ActivityShowType_Full) {
url = [url stringByAppendingFormat:@"&safeTop=1"];
}
break;
case MSGameTypeCC:
default:
break;
}
if (isMSEN()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"en-US"];
} else if (isMSTR()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"tr-TR"];
} else if (isMSZH()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"zh-TW"];
} else if (isMSRTL()) {
url = [url stringByAppendingFormat:@"&lang=%@", @"ar-EG"];
}
url = [url stringByAppendingFormat:@"&token=%@", self.gameModel.gameModel.code];
url = [url stringByAppendingFormat:@"&uid=%@", [AccountInfoStorage instance].getUid];
url = [url stringByAppendingFormat:@"&roomid=%ld", (long)self.hostDelegate.getRoomInfo.uid];
return [NSURL URLWithString:url];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[self hideHUD];
if (self.isBaiShun) {
} else {
self.retryCount = 0;
[self.loadingTimer invalidate];
self.loadingTimer = nil;
if (self.gameType != MSGameTypeBaiShun) {
self.backBtn.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight*0.3);
}
//
NSString *errorHandler = @"window.onerror = function(msg, url, line, col, error) { window.webkit.messageHandlers.error.postMessage({message: msg, url: url, line: line, col: col}); return false; }";
[webView evaluateJavaScript:errorHandler completionHandler:nil];
#if DEBUG
NSString *fileName = @"vconsole.min.js"; //
@@ -214,12 +364,33 @@ NSString * const kMSGameLoaded = @"gameLoaded";
#endif
}
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,card);
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
[self handleWebViewError:error];
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
[self handleWebViewError:error];
}
- (void)handleWebViewError:(NSError *)error {
if (self.retryCount < 3) {
self.retryCount++;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.webView loadRequest:self.lastRequest];
});
} else {
[self hideHUD];
[XNDJTDDLoadingTool showErrorWithMessage:@"网络连接失败,请稍后重试"];
}
}
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *card = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, card);
} else {
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
}
}
@@ -273,27 +444,45 @@ NSString * const kMSGameLoaded = @"gameLoaded";
didReceiveScriptMessage:(WKScriptMessage *)message
{
/// BaiShun
if (self.isBaiShun) {
NSDictionary *dicBody = [self dictionaryWithJsonString:message.body];
if ([message.name isEqualToString:kMSGetConfig]) {
[self getConfig:dicBody];
} else if ([message.name isEqualToString:kMSDestroy]) {
[self destroy:dicBody];
} else if ([message.name isEqualToString:kMSGameLoaded]) {
[self gameLoaded:dicBody];
} else if ([message.name isEqualToString:kMSGameRecharge]) {
[self gameRecharge:dicBody];
} else {
NSLog(@"未实现⽅法 : %@ --> %@", message.name, message.body);
switch (self.gameType) {
case MSGameTypeBaiShun: {
NSDictionary *dicBody = [self dictionaryWithJsonString:message.body];
if ([message.name isEqualToString:kMSGetConfig]) {
[self getConfig:dicBody];
} else if ([message.name isEqualToString:kMSDestroy]) {
[self destroy:dicBody];
} else if ([message.name isEqualToString:kMSGameLoaded]) {
[self gameLoaded:dicBody];
} else if ([message.name isEqualToString:kMSGameRecharge]) {
[self gameRecharge:dicBody];
} else {
NSLog(@"未实现⽅法 : %@ --> %@", message.name, message.body);
}
break;
}
} else {
/// LeaderCC
NSString* method = [NSString stringWithFormat:@"%@:", message.name];
SEL selector = NSSelectorFromString(method);
if([self respondsToSelector:selector]){
[self performSelector:selector withObject:message.body];
}else{
NSLog(@"未實現方法 : %@ --> %@", message.name, message.body);
case MSGameTypeJoyPlay: {
if ([message.name isEqualToString:kJPRecharge]) {
XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init];
webVC.type = @"4";
[self.navigationController pushViewController:webVC animated:YES];
self.isCharing = YES;
} else if ([message.name isEqualToString:kJPClickRecharge]) {
[self gameRecharge:@{}];
} else if ([message.name isEqualToString:kJPClose]) {
[self backBtnAction];
}
break;
}
case MSGameTypeCC: {
/// LeaderCC
NSString* method = [NSString stringWithFormat:@"%@:", message.name];
SEL selector = NSSelectorFromString(method);
if([self respondsToSelector:selector]){
[self performSelector:selector withObject:message.body];
}else{
NSLog(@"未實現方法 : %@ --> %@", message.name, message.body);
}
break;
}
}
}