提交sdk
This commit is contained in:
Vendored
BIN
Binary file not shown.
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76f10c0dfac51bf47a9d05b1595f36ed
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// CustomView.h
|
||||
// UnityFramework
|
||||
//
|
||||
// Created by Mac on 2024/1/19.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CustomView : UIView<WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
|
||||
+(id) shared;
|
||||
-(void)initView;
|
||||
//-(void)setConfig:(ViewCfg)cfg;
|
||||
-(void)userContentController:(WKUserContentController*) userContentController didReceiveScriptMessage:(WKScriptMessage*)message;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,27 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a21a679681cf0840ab2bd52bbd4b25d
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,40 +0,0 @@
|
||||
//
|
||||
// CustomView.m
|
||||
// UnityFramework
|
||||
//
|
||||
// Created by Mac on 2024/1/19.
|
||||
//
|
||||
|
||||
#import "CustomView.h"
|
||||
#import "H5View.h"
|
||||
@implementation CustomView
|
||||
{
|
||||
// WKWebView *webview;
|
||||
// UIView* unityView;
|
||||
// //ViewCfg config;
|
||||
// CGPoint hitTestLocation;
|
||||
// BOOL isTouchWebView;
|
||||
// BOOL isWebviewOpen;
|
||||
// BOOL canCT;
|
||||
int test;
|
||||
}
|
||||
+(id) shared{
|
||||
static CustomView *view = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
|
||||
dispatch_once(&onceToken, ^{view = [[self alloc] init];});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
-(void)initView{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
|
||||
UIView* testview = [ [H5View shared]hitTest:point withEvent:event];
|
||||
return testview;
|
||||
}
|
||||
@end
|
||||
@@ -1,42 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3c066056f7e4154ba1f1502fc224545
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
VisionOS: VisionOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,32 +0,0 @@
|
||||
//
|
||||
// H5View.h
|
||||
// TestGameWeb
|
||||
//
|
||||
// Created by Mac on 2024/1/30.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface H5View : UIView<WKUIDelegate, WKNavigationDelegate,WKScriptMessageHandler>
|
||||
+(id) shared;
|
||||
-(void)initView;
|
||||
-(void)showWebview:(NSString*)url;
|
||||
-(void)showDarkWebview:(int)type;
|
||||
-(void)showView:(BOOL)show;
|
||||
-(void)setIconProgress:(float)value;
|
||||
-(void)setViewPadding:(CGRect)rect;
|
||||
-(void)SetDarkThough:(BOOL)though;
|
||||
-(void)setViewBtn:(CGRect)rect;
|
||||
-(void)addH5Field:(int)field1 field2:(int)field2 field3:(int)field3 field4:(int)field4 field5:(int)field5 field6:(char* )field6 field7:(char* )field7 dark_url:(char*)dark_url light_url:(char*)light_url field8:(BOOL)field8 web_through_probability:(char*)web_through_probability click_add_time:(char*)click_add_time ;
|
||||
-(void)showFlyBtn:(BOOL)flag;
|
||||
-(void)setInH5View:(BOOL)flag;
|
||||
-(void)upDataH5times:(char*)weblink times:(int)times is_dark:(BOOL)is_dark;
|
||||
-(void)setFlyBtnTag:(BOOL)isShow;
|
||||
-(void)setRewardBtnTag:(BOOL)isShow;
|
||||
-(void)OpenWv;
|
||||
@end
|
||||
@interface H5View (WKNavigationDelegate) <WKNavigationDelegate>
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,27 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed2fcc18a0906294da953f4ba1005c10
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,893 +0,0 @@
|
||||
//
|
||||
// H5View.m
|
||||
// TestGameWeb
|
||||
//
|
||||
// Created by Mac on 2024/1/30.
|
||||
//
|
||||
|
||||
#import "H5View.h"
|
||||
#import <WebKit/WebKit.h>
|
||||
#import "CustomView.h"
|
||||
#import "UnityFramework.h"
|
||||
#import <objc/runtime.h>
|
||||
// 显式声明 Unity 的消息发送函数,防止编译器报错
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "UnityInterface.h"
|
||||
|
||||
@implementation H5View{
|
||||
|
||||
NSMutableArray<WKWebView *> *webviews;
|
||||
//奖励按钮进度条
|
||||
UIView * flyBtn; //飞行奖励按钮节点,也可以用UIButton但要屏蔽事件
|
||||
UIImageView* flyBg; //飞行奖励闪光背景
|
||||
UIImageView* rewardBtn; //奖励按钮节点
|
||||
NSTimer* updateTimer; //动效定时器
|
||||
CGPoint points[4]; //飞行按钮飞行点位
|
||||
NSInteger pointIndex; //当前飞行下标
|
||||
BOOL canFly; //是否可飞行
|
||||
CGPoint targetPoint; //飞行的下一个点
|
||||
CGPoint delta; //飞行移动的delta
|
||||
BOOL canCheckTouch; //加这个变量来防止检测点击事件出现多次
|
||||
BOOL canCT; //点击是否可穿透
|
||||
NSString* NullUrl; //空的的url
|
||||
BOOL inited; //当前view是否被初始化
|
||||
CGPoint hitTestLocation; //hitest 点击的点
|
||||
float bgAngle; //飞行按钮背景图的角度
|
||||
BOOL is_first_btn; //是否是第一次生成网页按钮
|
||||
int flyCtRate;//飞行按钮穿透概率
|
||||
float stopTouchTime;
|
||||
|
||||
int otherH5switch; //是否自动刷h5界面
|
||||
int H5Refreshtime; //h5刷新默认间隔时间
|
||||
// int Dailyrefreshtimes; //每天h5剩余刷新次数
|
||||
UIScrollView *scrollView;
|
||||
BOOL is_dark_mode;//是否是暗网页开启状态
|
||||
BOOL dark_though; //在暗网页开启时是否开启暗穿透
|
||||
NSMutableArray * dark_though_rate;//按穿透概率
|
||||
|
||||
NSMutableArray *Dark_stopRefeshTimes;//暗网页停止刷新时间,用来和刷新间隔判断来自动刷新
|
||||
|
||||
NSMutableArray *dark_H5Refreshtime; //h5刷新默认间隔时间
|
||||
|
||||
NSMutableArray *dark_url_array;
|
||||
BOOL inH5ui;
|
||||
|
||||
NSMutableArray *light_url_array;
|
||||
|
||||
BOOL isClickProgress;
|
||||
BOOL isClickFly;
|
||||
int light_though_rate;
|
||||
|
||||
|
||||
BOOL isShowFlyBtn;
|
||||
BOOL isShowRewardBtn;
|
||||
|
||||
int isMultiView;
|
||||
float top_;
|
||||
float height_;
|
||||
BOOL is_gift;
|
||||
|
||||
NSMutableArray *offset_y;
|
||||
NSMutableArray *web_clickweight_array;//接收点击的权重
|
||||
|
||||
|
||||
NSMutableArray *ClickAddtime;
|
||||
|
||||
NSMutableArray<NSNumber *> *web_through_times;//每层暗网页操作过去的时间,用来和禁用时间来对比
|
||||
|
||||
NSMutableArray<NSNumber *> *dark_webview_random_refresh_times;
|
||||
|
||||
|
||||
NSMutableArray<NSNumber *> *web_disable_times;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//单利模式
|
||||
+(id) shared{
|
||||
static H5View *view = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
|
||||
dispatch_once(&onceToken, ^{view = [[self alloc] init];});
|
||||
|
||||
return view;
|
||||
}
|
||||
//初始化页面
|
||||
-(void)initView{
|
||||
if (inited)return;
|
||||
[self setHidden:YES]; //默认为隐藏状态
|
||||
[self hideView];
|
||||
canCheckTouch = true;
|
||||
inited = true;
|
||||
|
||||
dark_though_rate= [NSMutableArray array];
|
||||
dark_webview_random_refresh_times = [NSMutableArray array];
|
||||
web_through_times= [NSMutableArray array];
|
||||
web_disable_times= [NSMutableArray array];
|
||||
Dark_stopRefeshTimes= [NSMutableArray array];
|
||||
webviews= [NSMutableArray array];
|
||||
offset_y=[NSMutableArray array];
|
||||
|
||||
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.1
|
||||
target:self
|
||||
selector:@selector(timerAction:)
|
||||
userInfo:nil
|
||||
repeats:YES];
|
||||
|
||||
// 将 timer 添加到 NSRunLoopCommonModes 模式
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
|
||||
|
||||
CustomView *custom = [[CustomView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
|
||||
custom.backgroundColor = [UIColor clearColor];
|
||||
custom.userInteractionEnabled=YES;
|
||||
|
||||
[self.window.rootViewController.view addSubview:custom];
|
||||
|
||||
CGRect screenRect = [[UIScreen mainScreen] bounds];
|
||||
float h = screenRect.size.height;
|
||||
self.frame = CGRectMake(0, 0,screenRect.size.width, screenRect.size.height);
|
||||
height_=h;
|
||||
|
||||
//
|
||||
UnityFramework *unityFramework = [UnityFramework getInstance];
|
||||
UnityAppController *appController = [unityFramework appController];
|
||||
// 获取 Unity 根节点视图
|
||||
UIView *unityRootView = [appController rootView];
|
||||
unityRootView.alpha=0.2;
|
||||
}
|
||||
|
||||
-(void)initWebview:(int)type{//创建webview的方法
|
||||
|
||||
if( webviews[type]!=nil){
|
||||
webviews[type].navigationDelegate = nil;
|
||||
|
||||
// 停止加载和清理缓存
|
||||
[webviews[type] stopLoading];
|
||||
[webviews[type] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
|
||||
[NSURLCache.sharedURLCache removeAllCachedResponses];
|
||||
|
||||
// 从视图层次结构中移除WebView
|
||||
[webviews[type] removeFromSuperview];
|
||||
webviews[type] = [NSNull null];
|
||||
}
|
||||
|
||||
WKWebViewConfiguration *webViewConfiguration = [[WKWebViewConfiguration alloc] init];
|
||||
|
||||
if(is_dark_mode){
|
||||
webViewConfiguration.allowsInlineMediaPlayback = YES;
|
||||
webViewConfiguration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
|
||||
|
||||
NSString *css = @"body { -webkit-user-select: none; user-select: none; }";
|
||||
NSString *jsCSS = [NSString stringWithFormat:
|
||||
@"var style = document.createElement('style'); "
|
||||
"style.innerHTML = '%@'; "
|
||||
"document.head.appendChild(style);", css];
|
||||
|
||||
NSString *js =
|
||||
@"(function() { "
|
||||
// 禁用所有表单元素
|
||||
"var elements = document.querySelectorAll('input, textarea, select'); "
|
||||
"elements.forEach(function(element) { "
|
||||
" element.disabled = true; "
|
||||
" element.setAttribute('readonly', 'true'); "
|
||||
"}); "
|
||||
|
||||
// 拦截 focus,强制失焦,防止输入法弹出
|
||||
"document.addEventListener('focusin', function(event) { "
|
||||
" if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA' || event.target.tagName === 'SELECT') { "
|
||||
" event.target.blur(); "
|
||||
" } "
|
||||
"}); "
|
||||
|
||||
// 禁用所有音频和视频
|
||||
"document.querySelectorAll('audio, video').forEach(function(el) { "
|
||||
" el.muted = true; "
|
||||
" el.pause(); "
|
||||
"}); "
|
||||
|
||||
// 处理触摸事件,阻止广告类元素的触摸
|
||||
"document.addEventListener('touchstart', function(event) { "
|
||||
" const target = event.target; "
|
||||
" if (target.matches('.ad-class') || target.closest('.ad-class')) { "
|
||||
" setTimeout(function() { "
|
||||
" const touchCancelEvent = new TouchEvent('touchcancel', { "
|
||||
" bubbles: true, "
|
||||
" cancelable: true, "
|
||||
" touches: [], "
|
||||
" targetTouches: [], "
|
||||
" changedTouches: event.changedTouches, "
|
||||
" shiftKey: event.shiftKey "
|
||||
" }); "
|
||||
" target.dispatchEvent(touchCancelEvent); "
|
||||
" }, 1000); "
|
||||
" event.preventDefault(); "
|
||||
" } "
|
||||
"}, { passive: false }); "
|
||||
|
||||
// 监控 DOM 变化,禁用新插入的输入框
|
||||
"new MutationObserver(function(mutations) { "
|
||||
" mutations.forEach(function(mutation) { "
|
||||
" mutation.addedNodes.forEach(function(node) { "
|
||||
" if (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA' || node.tagName === 'SELECT') { "
|
||||
" node.disabled = true; "
|
||||
" node.setAttribute('readonly', 'true'); "
|
||||
" node.blur(); "
|
||||
" } "
|
||||
" }); "
|
||||
" }); "
|
||||
"}).observe(document.body, { childList: true, subtree: true }); "
|
||||
|
||||
"})();";
|
||||
|
||||
NSString *combinedJS = [NSString stringWithFormat:@"%@ %@", jsCSS, js];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WKUserScript *userScript = [[WKUserScript alloc]
|
||||
initWithSource:combinedJS
|
||||
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
|
||||
forMainFrameOnly:NO];
|
||||
|
||||
[webViewConfiguration.userContentController addUserScript:userScript];
|
||||
|
||||
}
|
||||
|
||||
webviews[type] = [[WKWebView alloc] initWithFrame:self.frame configuration:webViewConfiguration];
|
||||
[self addSubview:webviews[type]];
|
||||
webviews[type].allowsLinkPreview = NO;
|
||||
[self insertSubview:webviews[type] atIndex:0];
|
||||
|
||||
|
||||
webviews[type] .alpha=0.5;
|
||||
|
||||
for (NSInteger i = 0; i < webviews.count; i++) {
|
||||
webviews[i].navigationDelegate=self;
|
||||
webviews[i].UIDelegate = self;
|
||||
}
|
||||
[self ChangeViewRect:!is_dark_mode];
|
||||
// [self showWebview:@"https://baidu.com"];
|
||||
|
||||
}
|
||||
|
||||
//当前view的显/隐
|
||||
-(void)showView:(BOOL)show{
|
||||
|
||||
if (!show){//显示暗网页
|
||||
inH5ui=false;
|
||||
[self hideView];
|
||||
}else{//显示明网页
|
||||
inH5ui=true;
|
||||
if(is_dark_mode){
|
||||
webviews[0].hidden=YES;
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@""] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
|
||||
[webviews[0] loadRequest:request];
|
||||
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delayShowH5) object:nil];
|
||||
[self performSelector:@selector(delayShowH5) withObject:nil afterDelay:1.5];
|
||||
}
|
||||
|
||||
|
||||
[self.superview bringSubviewToFront:self];
|
||||
|
||||
is_dark_mode=NO;
|
||||
if (isShowRewardBtn) {
|
||||
[rewardBtn setHidden:NO];
|
||||
} else {
|
||||
[rewardBtn setHidden:YES];
|
||||
}
|
||||
|
||||
[self showWebview:NullUrl]; //打开webview时url为上一次
|
||||
[self ChangeViewRect:true];
|
||||
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
||||
self .alpha=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//显示暗网页
|
||||
-(void)hideView{
|
||||
|
||||
if(!is_dark_mode){
|
||||
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@""] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
|
||||
for (NSInteger i = 0; i < webviews.count; i++) {
|
||||
webviews[i].hidden = YES;
|
||||
[ webviews[i] loadRequest:request];
|
||||
}
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delayShowH5) object:nil];
|
||||
[self performSelector:@selector(delayShowH5) withObject:nil afterDelay:0.5];
|
||||
}
|
||||
is_dark_mode=YES;
|
||||
|
||||
[self.superview sendSubviewToBack:self];
|
||||
|
||||
self.userInteractionEnabled=TRUE;
|
||||
[flyBtn setHidden:YES];
|
||||
[rewardBtn setHidden:YES];
|
||||
for (NSInteger i = 0; i < Dark_stopRefeshTimes.count; i++) {
|
||||
Dark_stopRefeshTimes[i]=@(0);
|
||||
}
|
||||
|
||||
|
||||
for (NSInteger i = 0; i < webviews.count; i++) {
|
||||
[self showDarkWebview:i];
|
||||
}
|
||||
|
||||
|
||||
[self ChangeViewRect:false];
|
||||
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
||||
self .alpha=0;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)delayShowH5{
|
||||
// webview.hidden=NO;
|
||||
// webview_1.hidden=NO;
|
||||
for (NSInteger i = 0; i < webviews.count; i++) {
|
||||
webviews[i].hidden=NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-(void)upDataH5times:(char*)weblink times:(int)times is_dark:(BOOL)is_dark{
|
||||
//
|
||||
// NSString *myNSString = [[NSString alloc] initWithUTF8String:weblink];
|
||||
// if(is_dark){
|
||||
// for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
//
|
||||
// if( [dark_url_array[counter][0] isEqualToString:myNSString]){
|
||||
// dark_url_array[counter][2]=@(times);
|
||||
//
|
||||
// dark_though_rate[[dark_url_array[counter][4] intValue]-1]=@([dark_url_array[counter][3] intValue]);
|
||||
//
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else{
|
||||
// for (int counter = 0; counter < light_url_array.count; counter++) {
|
||||
//
|
||||
// if( [light_url_array[counter][0] isEqualToString:myNSString]){
|
||||
// light_url_array[counter][2]=@(times);
|
||||
// //light_though_rate=[light_url_array[counter][3] intValue];
|
||||
// // NSLog(@"[uuuuuuuuuuuuuuuuu: %s剩余的可刷新次数%u", weblink, times);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)timerAction:(NSTimer *)timer {
|
||||
// 定时器触发时执行的操作
|
||||
// web_1_through_time+=0.1;
|
||||
// web_2_through_time+=0.1;
|
||||
for (NSUInteger i = 0; i < web_through_times.count; i++) {
|
||||
web_through_times[i] = @([web_through_times[i] floatValue] + 0.1f);
|
||||
// NSLog(@"[uuuuuuuuuuuuuuuuu未穿透时间: %f",[web_through_times[i] floatValue]);
|
||||
}
|
||||
|
||||
|
||||
stopTouchTime+=0.1;
|
||||
for (NSInteger i = 0; i < Dark_stopRefeshTimes.count; i++) {
|
||||
Dark_stopRefeshTimes[i]=@([Dark_stopRefeshTimes[i ] floatValue ] +0.1f);
|
||||
}
|
||||
|
||||
// Dark_stopRefeshTime+=0.1;
|
||||
// Dark_stopRefeshTime_1+=0.1;
|
||||
|
||||
|
||||
if(is_dark_mode){
|
||||
for(NSUInteger i=0;i<webviews.count;i++){
|
||||
|
||||
bool have_refresh_numbres=false;
|
||||
for(NSUInteger j=0;j<dark_url_array.count;j++){
|
||||
if(([dark_url_array[j][4] intValue]==(i+1))&&([dark_url_array[j][4] intValue]>0)){
|
||||
have_refresh_numbres=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(have_refresh_numbres&&
|
||||
[Dark_stopRefeshTimes[i]floatValue]>[dark_webview_random_refresh_times[i]intValue]){
|
||||
|
||||
// dark_Dailyrefreshtimes[i]=@([dark_Dailyrefreshtimes[i] intValue]-1);
|
||||
Dark_stopRefeshTimes[i]=@(0);
|
||||
dark_webview_random_refresh_times[i]=@([dark_H5Refreshtime[i*2] intValue] + arc4random_uniform([dark_H5Refreshtime[i*2+1] intValue] - [dark_H5Refreshtime[i*2] intValue] + 1));
|
||||
// NSLog(@"hhhhhhhhhhhh3333333kkkk%d",[dark_webview_random_refresh_times[0] intValue]);
|
||||
//
|
||||
|
||||
|
||||
[self showDarkWebview:i];
|
||||
[self ChangeViewRect:false];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else{
|
||||
// if(Dailyrefreshtimes<=0 ) return;
|
||||
bool have_numbers=false;
|
||||
for (int counter = 0; counter < light_url_array.count; counter++) {
|
||||
if ([light_url_array[counter][2] intValue] > 0) {
|
||||
have_numbers=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!have_numbers) return;
|
||||
|
||||
if(stopTouchTime>H5Refreshtime){
|
||||
[self showWebview:NullUrl];
|
||||
[self ChangeViewRect:true];
|
||||
stopTouchTime=0;
|
||||
// Dailyrefreshtimes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//显示明网页
|
||||
-(void)showWebview:(NSString*)url{
|
||||
if (is_dark_mode) return; //view在隐藏状态下不显示webview,因为目前只需要处理明webview 的显示。
|
||||
[self initWebview:0];
|
||||
int maxvalue = 0;
|
||||
// 1. 第一次遍历:计算剩余次数大于 0 的总权重
|
||||
for (int counter = 0; counter < light_url_array.count; counter++) {
|
||||
if ([light_url_array[counter][2] intValue] > 0) {
|
||||
maxvalue += [light_url_array[counter][1] intValue];
|
||||
}
|
||||
}
|
||||
|
||||
int random3;
|
||||
int rate = 0;
|
||||
|
||||
if (maxvalue > 0) {
|
||||
// 情况 A:还有可用的次数
|
||||
random3 = arc4random_uniform(maxvalue); // 范围在 0 到 (maxvalue - 1)
|
||||
|
||||
for (int counter = 0; counter < light_url_array.count; counter++) {
|
||||
if ([light_url_array[counter][2] intValue] == 0) continue;
|
||||
|
||||
int myInt = [light_url_array[counter][1] intValue];
|
||||
rate += myInt;
|
||||
|
||||
if (random3 < rate) { // 修改为严格小于,配合 arc4random_uniform
|
||||
url = light_url_array[counter][0];
|
||||
// 次数正确减 1,并保持 int 类型的包装
|
||||
light_url_array[counter][2] = @([light_url_array[counter][2] intValue] - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 情况 B 兜底:所有 URL 的次数都用完了,重新计算不看次数的绝对总权重
|
||||
int absoluteTotalWeight = 0;
|
||||
for (int counter = 0; counter < light_url_array.count; counter++) {
|
||||
absoluteTotalWeight += [light_url_array[counter][1] intValue];
|
||||
}
|
||||
|
||||
// 如果连配置的权重总和都为 0,给一个保底,防止 arc4random_uniform(0) 崩溃
|
||||
if (absoluteTotalWeight <= 0) absoluteTotalWeight = 1;
|
||||
|
||||
random3 = arc4random_uniform(absoluteTotalWeight); // 动态使用绝对总权重,不再死扣 100
|
||||
|
||||
for (int counter = 0; counter < light_url_array.count; counter++) {
|
||||
int myInt = [light_url_array[counter][1] intValue];
|
||||
rate += myInt;
|
||||
|
||||
if (random3 < rate) {
|
||||
url = light_url_array[counter][0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopTouchTime=0;
|
||||
if(url.length==0) return;
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] ];
|
||||
[webviews[0] loadRequest:request];
|
||||
if (webviews[0].superview == nil)
|
||||
[self insertSubview:webviews[0] atIndex:0];
|
||||
UnitySendMessage("SdkManager", "UpdateNumbers",[[url stringByAppendingString:@"|h5"] UTF8String]);
|
||||
}
|
||||
|
||||
|
||||
-(void)showDarkWebview:(int)type{//显示暗网页
|
||||
if(!is_gift) return;
|
||||
[self initWebview:type];
|
||||
NSString* url=@"";
|
||||
|
||||
int maxvalue = 0;
|
||||
// 1. 第一次遍历:计算【次数>0】且【类型匹配】的总权重
|
||||
for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
if ([dark_url_array[counter][2] intValue] > 0) {
|
||||
// 类型过滤
|
||||
if ([dark_url_array[counter][4] intValue] != (type + 1)) continue;
|
||||
|
||||
maxvalue += [dark_url_array[counter][1] intValue];
|
||||
}
|
||||
}
|
||||
|
||||
int random3;
|
||||
int rate = 0;
|
||||
|
||||
if (maxvalue > 0) {
|
||||
// 情况 A:有符合类型且有次数的 URL
|
||||
random3 = arc4random_uniform(maxvalue);
|
||||
|
||||
for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
if ([dark_url_array[counter][2] intValue] <= 0) continue;
|
||||
if ([dark_url_array[counter][4] intValue] != (type + 1)) continue;
|
||||
|
||||
// 修正拼写:同步费率/比率数据到 dark_though_rate
|
||||
int targetIndex = [dark_url_array[counter][4] intValue] - 1;
|
||||
dark_though_rate[targetIndex] = @([dark_url_array[counter][3] intValue]);
|
||||
|
||||
int myInt = [dark_url_array[counter][1] intValue];
|
||||
rate += myInt;
|
||||
|
||||
if (random3 < rate) {
|
||||
url = dark_url_array[counter][0];
|
||||
|
||||
dark_url_array[counter][2] = @([dark_url_array[counter][2] intValue] - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 情况 B 兜底:符合该类型的 URL 次数全用完了,重新计算该类型的绝对总权重
|
||||
int absoluteTotalWeight = 0;
|
||||
for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
if ([dark_url_array[counter][4] intValue] != (type + 1)) continue;
|
||||
absoluteTotalWeight += [dark_url_array[counter][1] intValue];
|
||||
}
|
||||
|
||||
// 防崩溃保底
|
||||
if (absoluteTotalWeight <= 0) absoluteTotalWeight = 1;
|
||||
|
||||
random3 = arc4random_uniform(absoluteTotalWeight); // 动态使用绝对总权重
|
||||
|
||||
for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
if ([dark_url_array[counter][4] intValue] != (type + 1)) continue;
|
||||
|
||||
// 修正拼写:同步费率/比率数据到 dark_though_rate
|
||||
int targetIndex = [dark_url_array[counter][4] intValue] - 1;
|
||||
dark_though_rate[targetIndex] = @([dark_url_array[counter][3] intValue]);
|
||||
|
||||
int myInt = [dark_url_array[counter][1] intValue];
|
||||
rate += myInt;
|
||||
|
||||
if (random3 < rate) {
|
||||
url = dark_url_array[counter][0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// float maxvalue=0;
|
||||
// float random3 ;
|
||||
// float rate=0;
|
||||
//
|
||||
//
|
||||
//
|
||||
// for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
// if([dark_url_array[counter][2] intValue]>0 ){
|
||||
// if([dark_url_array[counter][4] intValue]!=(type+1) ) continue;
|
||||
// maxvalue+=[dark_url_array[counter][1] floatValue];
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if(maxvalue>0){
|
||||
// random3=arc4random_uniform(maxvalue);
|
||||
// for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
// if([dark_url_array[counter][2] intValue]<=0) continue;
|
||||
// if([dark_url_array[counter][4] intValue]!=(type+1) ) continue;
|
||||
// float myFloat = [dark_url_array[counter][1] floatValue];
|
||||
// dark_though_rate[[dark_url_array[counter][4] intValue]-1]=@([dark_url_array[counter][3] intValue]);
|
||||
// rate+=myFloat;
|
||||
// if(random3<=rate){
|
||||
// url=dark_url_array[counter][0];
|
||||
// dark_url_array[counter][2]=@([dark_url_array[counter][2] floatValue]-1);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else{
|
||||
// random3=arc4random_uniform(100);
|
||||
// for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
// if([dark_url_array[counter][4] intValue]!=(type+1) ) continue;
|
||||
// float myFloat = [dark_url_array[counter][1] floatValue];
|
||||
// dark_though_rate[[dark_url_array[counter][4] intValue]-1]=@([dark_url_array[counter][3] intValue]);
|
||||
// rate+=myFloat;
|
||||
// if(random3<=rate){
|
||||
// url=dark_url_array[counter][0];
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
|
||||
if(url.length==0) return;
|
||||
|
||||
[webviews[type] loadRequest:request];
|
||||
UnitySendMessage("SdkManager", "UpdateNumbers",[[url stringByAppendingString:@"|h6"] UTF8String]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//hitTest 能在不接受点击事件的view也能捕获多点位的信息
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
|
||||
hitTestLocation = point;
|
||||
// if(inH5ui&& hitTestLocation.y<100){
|
||||
// hitTestLocation.y+=66;
|
||||
// }
|
||||
//
|
||||
UIView* touchedView;
|
||||
int click_web=0;
|
||||
|
||||
if(!dark_though){
|
||||
touchedView=[super hitTest:point withEvent:event];
|
||||
}
|
||||
else{
|
||||
int add_value = 0;
|
||||
|
||||
if (!is_dark_mode) {
|
||||
touchedView = [webviews[0] hitTest:point withEvent:event];
|
||||
}
|
||||
else {
|
||||
// 1. 动态计算权重总和
|
||||
int total_weight = 0;
|
||||
for (NSUInteger i = 0; i < web_clickweight_array.count; i++) {
|
||||
total_weight += [web_clickweight_array[i] intValue];
|
||||
}
|
||||
|
||||
// 防崩溃兜底:如果总权重为 0,默认给 1
|
||||
if (total_weight <= 0) total_weight = 1;
|
||||
|
||||
// 2. 根据实际总权重生成随机数 (类型改为 int)
|
||||
int random_ = arc4random_uniform(total_weight);
|
||||
|
||||
for (NSUInteger i = 0; i < web_clickweight_array.count; i++) {
|
||||
int current_weight = [web_clickweight_array[i] intValue];
|
||||
|
||||
// 3. 判断是否落入当前权重区间 (使用严格小于号 < 配合 arc4random_uniform)
|
||||
if (random_ < add_value + current_weight) {
|
||||
touchedView = [webviews[i] hitTest:point withEvent:event];
|
||||
click_web = i;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
add_value += current_weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(is_dark_mode&&dark_though){//暗穿透
|
||||
|
||||
float random3 = arc4random_uniform(100) ;
|
||||
NSUInteger index = (isMultiView > 1) ? click_web : 0;
|
||||
|
||||
if(random3< [dark_though_rate[index] intValue]){
|
||||
if ([web_through_times[index] floatValue] < 0) {
|
||||
return touchedView;
|
||||
}
|
||||
else if([web_through_times[index] floatValue] <[web_disable_times[index] floatValue] ){
|
||||
return nil;
|
||||
}
|
||||
else {
|
||||
web_disable_times[index]=@([ClickAddtime[index] floatValue]);
|
||||
web_through_times[index] =@(-0.05);
|
||||
// NSLog(@"触发点击,时间设置为-0.5:%f",web_1_through_time);
|
||||
return touchedView;
|
||||
}
|
||||
}
|
||||
else return nil;
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if(isClickProgress&&!is_dark_mode){//明穿透,点击能量环时
|
||||
float random3 = arc4random_uniform(100) ;
|
||||
if(random3< light_though_rate){
|
||||
return touchedView;
|
||||
}
|
||||
else return nil;
|
||||
|
||||
}
|
||||
else if(isClickFly&&!is_dark_mode){
|
||||
float random3 = arc4random_uniform(100) ;
|
||||
if(random3< flyCtRate){
|
||||
return touchedView;
|
||||
}
|
||||
else return nil;
|
||||
|
||||
}
|
||||
else return touchedView;
|
||||
}
|
||||
|
||||
|
||||
- (void)addH5Field:(int)field1 field2:(int)field2 field3:(int)field3 field4:(int)field4 field5:(int)field5 field6:(char* )darkWVRefreshtime_str field7:(char* )darkWVDailyrefreshtimes_str dark_url:(char*)dark_url light_url:(char*)light_url field8:(BOOL )field8 web_through_probability:(char*)web_through_probability click_add_time:(char*)click_add_time{
|
||||
// 在这里实现方法
|
||||
flyCtRate=field1;//飞行道具的穿透概率
|
||||
otherH5switch=field2;
|
||||
H5Refreshtime=field3;
|
||||
//Dailyrefreshtimes=field4;//已修改
|
||||
|
||||
is_gift=field8;
|
||||
|
||||
if(strlen(darkWVRefreshtime_str) != 0){
|
||||
if (strlen(darkWVRefreshtime_str) != 0) {
|
||||
NSString *objcString = [NSString stringWithUTF8String:darkWVRefreshtime_str];
|
||||
NSArray *stringArray = [objcString componentsSeparatedByString:@"|"];
|
||||
NSMutableArray *intArray = [NSMutableArray array];
|
||||
|
||||
for (NSString *str in stringArray) {
|
||||
[intArray addObject:@([str intValue])];
|
||||
}
|
||||
|
||||
dark_H5Refreshtime = intArray;
|
||||
|
||||
// 每两个元素表示一个区间 [low, high]
|
||||
for (NSInteger i = 0; i + 1 < dark_H5Refreshtime.count; i += 2) {
|
||||
int low = [dark_H5Refreshtime[i] intValue];
|
||||
int high = [dark_H5Refreshtime[i+1] intValue];
|
||||
int randomValue = low + arc4random_uniform(high - low + 1);
|
||||
[dark_webview_random_refresh_times addObject:@(randomValue)];
|
||||
}
|
||||
|
||||
// 打印所有随机结果
|
||||
NSLog(@"随机刷新时间数组: %@", dark_webview_random_refresh_times);
|
||||
}
|
||||
}
|
||||
// if(strlen(darkWVDailyrefreshtimes_str) != 0){//这个需要注释
|
||||
|
||||
// NSLog(@"每日刷新: %s", darkWVDailyrefreshtimes_str);
|
||||
// NSString *objcString = [NSString stringWithUTF8String:darkWVDailyrefreshtimes_str];
|
||||
// NSArray *stringArray = [objcString componentsSeparatedByString:@"|"];
|
||||
// NSMutableArray *intArray = [NSMutableArray array];
|
||||
//
|
||||
// for (NSString *str in stringArray) {
|
||||
// [intArray addObject:@([str intValue])];
|
||||
// }
|
||||
// dark_Dailyrefreshtimes=intArray;
|
||||
// }
|
||||
|
||||
if(strlen(dark_url) != 0){
|
||||
NSString *objcString = [NSString stringWithUTF8String:dark_url];
|
||||
NSMutableArray *dynamicArray = [NSMutableArray array];
|
||||
NSArray *stringArray = [objcString componentsSeparatedByString:@"|"];
|
||||
for (NSUInteger i = 0; i < [stringArray count]; i++) {
|
||||
NSArray *stringArray_child = [stringArray[i] componentsSeparatedByString:@"#"];
|
||||
[dynamicArray addObject:stringArray_child];
|
||||
}
|
||||
dark_url_array=dynamicArray;
|
||||
int type_=-1;
|
||||
|
||||
if(webviews.count<=0){
|
||||
isMultiView=0;
|
||||
for (int counter = 0; counter < dark_url_array.count; counter++) {
|
||||
|
||||
if([dark_url_array[counter][4] intValue]!=type_ ) {
|
||||
isMultiView++;
|
||||
type_=[dark_url_array[counter][4] intValue];
|
||||
[dark_though_rate addObject:@0];//已修改
|
||||
|
||||
[web_through_times addObject:@0];
|
||||
[web_disable_times addObject:@0];
|
||||
[Dark_stopRefeshTimes addObject:@0];
|
||||
[offset_y addObject:@([dark_url_array[counter][5] intValue])];
|
||||
WKWebView *wv = [[WKWebView alloc] initWithFrame:CGRectZero];
|
||||
[webviews addObject:wv];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(strlen(light_url) != 0){
|
||||
NSString *objcString = [NSString stringWithUTF8String:light_url];
|
||||
NSMutableArray *dynamicArray = [NSMutableArray array];
|
||||
NSArray *stringArray = [objcString componentsSeparatedByString:@"|"];
|
||||
for (NSUInteger i = 0; i < [stringArray count]; i++) {
|
||||
NSArray *stringArray_child = [stringArray[i] componentsSeparatedByString:@"#"];
|
||||
|
||||
[dynamicArray addObject:stringArray_child];
|
||||
}
|
||||
light_url_array=dynamicArray;
|
||||
}
|
||||
if(strlen(web_through_probability) != 0){
|
||||
NSString *objcString = [NSString stringWithUTF8String:web_through_probability];
|
||||
NSArray *stringArray = [objcString componentsSeparatedByString:@"|"];
|
||||
NSMutableArray *intArray = [NSMutableArray array];
|
||||
|
||||
for (NSString *str in stringArray) {
|
||||
[intArray addObject:@([str intValue])];
|
||||
}
|
||||
web_clickweight_array=intArray;
|
||||
}
|
||||
if(strlen(click_add_time) != 0){
|
||||
NSString *objcString = [NSString stringWithUTF8String:click_add_time];
|
||||
NSArray *stringArray = [objcString componentsSeparatedByString:@"|"];
|
||||
NSMutableArray *intArray = [NSMutableArray array];
|
||||
|
||||
for (NSString *str in stringArray) {
|
||||
[intArray addObject:@([str floatValue])];
|
||||
}
|
||||
ClickAddtime=intArray;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//设置view的padding
|
||||
-(void)setViewPadding:(CGRect)rect{
|
||||
CGRect screenRect = [[UIScreen mainScreen] bounds];
|
||||
float top = rect.origin.y*screenRect.size.height;
|
||||
float bottom = rect.size.height*screenRect.size.height;
|
||||
float h = screenRect.size.height - top - bottom;
|
||||
self.frame = CGRectMake(0, 0,screenRect.size.width, screenRect.size.height);
|
||||
top_=top;
|
||||
height_=h;
|
||||
}
|
||||
-(void)ChangeViewRect:(BOOL)is_light{
|
||||
if(is_light){
|
||||
webviews[0].frame = CGRectMake(0, top_, self.frame.size.width, height_);
|
||||
for(NSUInteger i=1;i<webviews.count;i++){
|
||||
webviews[i].frame = CGRectMake(0, 0,0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
for(NSUInteger i=0;i<webviews.count;i++){
|
||||
webviews[i].frame = CGRectMake(0, [offset_y[i] intValue], self.frame.size.width, self.frame.size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)SetDarkThough:(BOOL)though{
|
||||
dark_though=though;
|
||||
[self setHidden:!though];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//延迟执行逻辑
|
||||
-(void)delayInvoke:(float)delay cb:(dispatch_block_t)cb{
|
||||
NSTimeInterval delayInSeconds = delay;
|
||||
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
|
||||
dispatch_after(popTime, dispatch_get_main_queue(), cb);
|
||||
}
|
||||
|
||||
//飞行按钮隐/藏
|
||||
|
||||
-(void)OpenWv{
|
||||
|
||||
UIView* unityView = UnityGetGLView();
|
||||
|
||||
UIViewController *vc = [UIViewController new];
|
||||
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
[unityView.window setRootViewController:vc];
|
||||
vc.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
[vc.view addSubview:unityView];
|
||||
H5View *hview;
|
||||
hview = [H5View shared];
|
||||
[vc.view addSubview:hview];
|
||||
[hview setFrame:unityView.window.bounds];
|
||||
[hview initView];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
@@ -1,42 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e67e39822e0e24c4382e8824ecf04220
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
VisionOS: VisionOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,200 +0,0 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
extern UIView *UnityGetGLView(void);
|
||||
|
||||
@interface UIApplication (UnityTouchHook)
|
||||
- (void)ut_sendEvent:(UIEvent *)event;
|
||||
@end
|
||||
|
||||
@implementation UIApplication (UnityTouchHook)
|
||||
|
||||
// ==========================================
|
||||
// 【实装优化】:将 Ivar、Class 提取为静态全局变量,在 +load 中一次性缓存
|
||||
static CFTimeInterval g_lastMovedTime = 0;
|
||||
static Class g_touchClass = Nil;
|
||||
static Ivar g_ivarView = NULL;
|
||||
static Ivar g_ivarLocation = NULL;
|
||||
static Ivar g_ivarPrevLocation = NULL;
|
||||
// ==========================================
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
Class cls = [UIApplication class];
|
||||
Method original = class_getInstanceMethod(cls, @selector(sendEvent:));
|
||||
Method swizzled = class_getInstanceMethod(cls, @selector(ut_sendEvent:));
|
||||
|
||||
if (original && swizzled) {
|
||||
method_exchangeImplementations(original, swizzled);
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 【实装优化】:在 +load 时集中初始化,彻底消灭每帧的 Runtime 检索开销
|
||||
g_touchClass = [UITouch class];
|
||||
g_ivarView = class_getInstanceVariable(g_touchClass, "_view");
|
||||
g_ivarLocation = class_getInstanceVariable(g_touchClass, "_locationInWindow");
|
||||
g_ivarPrevLocation = class_getInstanceVariable(g_touchClass, "_previousLocationInWindow");
|
||||
// ==========================================
|
||||
});
|
||||
}
|
||||
|
||||
- (void)ut_sendEvent:(UIEvent *)event
|
||||
{
|
||||
// 1. 让系统和 WebView 先走正常响应
|
||||
[self ut_sendEvent:event];
|
||||
|
||||
if (event.type != UIEventTypeTouches)
|
||||
return;
|
||||
|
||||
UIView *unityView = UnityGetGLView();
|
||||
if (!unityView)
|
||||
return;
|
||||
|
||||
NSSet *touches = event.allTouches;
|
||||
UITouch *touch = [touches anyObject];
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
// 2. 拦截所有来自 WebView 或非 UnityView 的点击
|
||||
if (touch.view != unityView && ![touch.view isDescendantOfView:unityView]) {
|
||||
|
||||
UITouchPhase phase = touch.phase;
|
||||
|
||||
if (phase == UITouchPhaseMoved) {
|
||||
CFTimeInterval currentTime = CACurrentMediaTime();
|
||||
if (currentTime - g_lastMovedTime < 0.016) {
|
||||
return;
|
||||
}
|
||||
g_lastMovedTime = currentTime;
|
||||
}
|
||||
|
||||
// 【优化成果】:直接使用 self 获取 keyWindow
|
||||
UIWindow *window = self.keyWindow;
|
||||
if (!window && unityView.window) {
|
||||
window = unityView.window;
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 【实装优化】:window == nil 时提前返回,防止后续无意义计算与 KVC 崩溃风险
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
// ==========================================
|
||||
|
||||
// 【优化成果】:提取 locationInView 只计算一次
|
||||
CGPoint pointInWindow = [touch locationInView:window];
|
||||
CGPoint pointPrevWindow = [touch previousLocationInView:window];
|
||||
|
||||
CGPoint originalLocationStruct = pointInWindow;
|
||||
CGPoint originalPrevLocationStruct = pointPrevWindow;
|
||||
|
||||
// 【优化成果】:砍掉 convertPoint:fromView: 的矩阵计算
|
||||
CGPoint pointInUnity = pointInWindow;
|
||||
CGRect unityFrame = unityView.frame;
|
||||
if (unityFrame.origin.x != 0 || unityFrame.origin.y != 0) {
|
||||
pointInUnity.x -= unityFrame.origin.x;
|
||||
pointInUnity.y -= unityFrame.origin.y;
|
||||
}
|
||||
|
||||
// 【优化安全加固】:保留最后一道防线,防御极端情况下的 NaN / Inf
|
||||
if (isnan(pointInUnity.x) || isinf(pointInUnity.x)) pointInUnity.x = 0;
|
||||
if (isnan(pointInUnity.y) || isinf(pointInUnity.y)) pointInUnity.y = 0;
|
||||
|
||||
// 【优化成果】:在栈上缓存一次 bounds 结构体
|
||||
CGRect bounds = unityView.bounds;
|
||||
CGFloat viewWidth = bounds.size.width <= 0 ? 375 : bounds.size.width;
|
||||
CGFloat viewHeight = bounds.size.height <= 0 ? 812 : bounds.size.height;
|
||||
|
||||
// 【优化成果】:改用利于 CPU 分支预测的 if-else 约束范围
|
||||
if (pointInUnity.x < 0) {
|
||||
pointInUnity.x = 0;
|
||||
} else if (pointInUnity.x > viewWidth) {
|
||||
pointInUnity.x = viewWidth;
|
||||
}
|
||||
|
||||
if (pointInUnity.y < 0) {
|
||||
pointInUnity.y = 0;
|
||||
} else if (pointInUnity.y > viewHeight) {
|
||||
pointInUnity.y = viewHeight;
|
||||
}
|
||||
|
||||
CGPoint finalInjectPoint = pointInUnity;
|
||||
|
||||
// 3. 备份原始值(后续无需重复获取 Ivar,直接使用静态全局变量)
|
||||
UIView *originalView = touch.view;
|
||||
NSValue *originalLocation = nil;
|
||||
NSValue *originalPrevLocation = nil;
|
||||
|
||||
if (g_ivarLocation) {
|
||||
originalLocation = [touch valueForKey:@"locationInWindow"];
|
||||
}
|
||||
if (g_ivarPrevLocation) {
|
||||
originalPrevLocation = [touch valueForKey:@"previousLocationInWindow"];
|
||||
}
|
||||
|
||||
// 4. 【强制临时修改】重写原生 touch
|
||||
if (g_ivarView) {
|
||||
object_setIvar(touch, g_ivarView, unityView);
|
||||
} else {
|
||||
[touch setValue:unityView forKey:@"view"];
|
||||
}
|
||||
|
||||
if (g_ivarLocation) object_setIvar(touch, g_ivarLocation, [NSValue valueWithCGPoint:finalInjectPoint]);
|
||||
|
||||
// 计算 Moved 阶段的伪造历史坐标
|
||||
if (phase == UITouchPhaseMoved && originalLocation && originalPrevLocation) {
|
||||
CGPoint offset = CGPointMake(originalLocationStruct.x - originalPrevLocationStruct.x, originalLocationStruct.y - originalPrevLocationStruct.y);
|
||||
CGPoint fakePrevPoint = CGPointMake(finalInjectPoint.x - offset.x, finalInjectPoint.y - offset.y);
|
||||
|
||||
if (isnan(fakePrevPoint.x) || isinf(fakePrevPoint.x)) fakePrevPoint.x = finalInjectPoint.x;
|
||||
if (isnan(fakePrevPoint.y) || isinf(fakePrevPoint.y)) fakePrevPoint.y = finalInjectPoint.y;
|
||||
|
||||
if (fakePrevPoint.x < 0) {
|
||||
fakePrevPoint.x = 0;
|
||||
} else if (fakePrevPoint.x > viewWidth) {
|
||||
fakePrevPoint.x = viewWidth;
|
||||
}
|
||||
|
||||
if (fakePrevPoint.y < 0) {
|
||||
fakePrevPoint.y = 0;
|
||||
} else if (fakePrevPoint.y > viewHeight) {
|
||||
fakePrevPoint.y = viewHeight;
|
||||
}
|
||||
|
||||
if (g_ivarPrevLocation) object_setIvar(touch, g_ivarPrevLocation, [NSValue valueWithCGPoint:fakePrevPoint]);
|
||||
} else {
|
||||
if (g_ivarPrevLocation) object_setIvar(touch, g_ivarPrevLocation, [NSValue valueWithCGPoint:finalInjectPoint]);
|
||||
}
|
||||
|
||||
[touch setValue:[NSValue valueWithCGPoint:finalInjectPoint] forKey:@"locationInWindow"];
|
||||
|
||||
// 5. 将清洗干净的事件丢给 UnityView 通道
|
||||
switch (phase) {
|
||||
case UITouchPhaseBegan: [unityView touchesBegan:touches withEvent:event]; break;
|
||||
case UITouchPhaseMoved: [unityView touchesMoved:touches withEvent:event]; break;
|
||||
case UITouchPhaseEnded: [unityView touchesEnded:touches withEvent:event]; break;
|
||||
case UITouchPhaseCancelled: [unityView touchesCancelled:touches withEvent:event]; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// 6. 立刻恢复现场
|
||||
if (g_ivarView) {
|
||||
object_setIvar(touch, g_ivarView, originalView);
|
||||
} else {
|
||||
[touch setValue:originalView forKey:@"view"];
|
||||
}
|
||||
|
||||
if (g_ivarLocation && originalLocation) {
|
||||
object_setIvar(touch, g_ivarLocation, originalLocation);
|
||||
[touch setValue:originalLocation forKey:@"locationInWindow"];
|
||||
}
|
||||
if (g_ivarPrevLocation && originalPrevLocation) {
|
||||
object_setIvar(touch, g_ivarPrevLocation, originalPrevLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,42 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad8514b5149d03249914cf5607fed5d8
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
VisionOS: VisionOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
extern "C" {
|
||||
#include "H5View.h"
|
||||
NSString *stringFromChar(const char *input) {
|
||||
return [NSString stringWithUTF8String: input];
|
||||
}
|
||||
|
||||
void ShowH5View(bool flag){//显示明或暗网页
|
||||
[[H5View shared] showView:flag];
|
||||
}
|
||||
void addH5Field(int field1 ,int field2,int field3,int field4,int field5 ,char* field6 ,char* field7 ,char* dark_url,char* light_url, bool field8 , char* web_through_probability, char* click_add_time){
|
||||
[[H5View shared] addH5Field:field1 field2:field2 field3:field3 field4:field4 field5:field5 field6:field6 field7:field7 dark_url:dark_url light_url:light_url field8:field8 web_through_probability:web_through_probability click_add_time:click_add_time];
|
||||
}
|
||||
void SetPadding(float left, float top, float right, float bottom){
|
||||
[[H5View shared] setViewPadding:CGRectMake(left, top, right, bottom)];
|
||||
}
|
||||
void SetDarkThough(bool though){
|
||||
[[H5View shared] SetDarkThough:though];
|
||||
}
|
||||
void SetBtn(int left, int top, int right, int bottom){
|
||||
[[H5View shared] setViewBtn:CGRectMake(left, top, right, bottom)];
|
||||
}
|
||||
|
||||
void SetIconProgress(float val){
|
||||
[[H5View shared] setIconProgress:val];
|
||||
}
|
||||
|
||||
void ShowFlyBtn(bool show){
|
||||
[[H5View shared] showFlyBtn:show];
|
||||
}
|
||||
void setFlyBtnTag (bool show) {
|
||||
[[H5View shared] setFlyBtnTag: show];
|
||||
}
|
||||
void setRewardBtnTag (bool show) {
|
||||
[[H5View shared] setRewardBtnTag: show];
|
||||
}
|
||||
void OpenWv (bool show) {
|
||||
[[H5View shared] OpenWv];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43fc3492dbd38584e8ff2dec9ae5acdf
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
VisionOS: VisionOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user