提交h5修改
This commit is contained in:
+23487
-23537
File diff suppressed because it is too large
Load Diff
@@ -14,23 +14,18 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
-(void)initView;
|
||||
-(void)showWebview:(NSString*)url;
|
||||
-(void)showDarkWebview:(int)type;
|
||||
-(void)hideWebview;
|
||||
-(void)showView:(BOOL)show;
|
||||
-(void)setIconProgress:(float)value;
|
||||
-(void)setViewPadding:(CGRect)rect;
|
||||
-(void)SetDarkThough:(BOOL)though;
|
||||
-(void)setViewBtn:(CGRect)rect;
|
||||
-(void)setFullScreen;
|
||||
-(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)setClickView;
|
||||
-(void)enableCT:(BOOL)flag;
|
||||
-(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)SetOffset:(int)offsety offset_y1:(int)offsety1;
|
||||
|
||||
-(void)OpenWv;
|
||||
@end
|
||||
@interface H5View (WKNavigationDelegate) <WKNavigationDelegate>
|
||||
@end
|
||||
|
||||
+317
-792
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,200 @@
|
||||
#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
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2a4dc0b221fa49fca5e51faef064233
|
||||
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:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -5,67 +5,11 @@ extern "C" {
|
||||
return [NSString stringWithUTF8String: input];
|
||||
}
|
||||
|
||||
// void OpenWebview(char* url) {
|
||||
// [[CustomView shared] showWebview:stringFromChar(url)];
|
||||
// }
|
||||
|
||||
// void CloseWebview(){
|
||||
// [[CustomView shared] hideWebview];
|
||||
// }
|
||||
|
||||
// void SetSize(float x, float y, float width, float height){
|
||||
// [[CustomView shared] setWebviewSize:CGRectMake(x, y, width, height)];
|
||||
// }
|
||||
|
||||
// void SetFullScreen(){
|
||||
// [[CustomView shared] setFullScreen];
|
||||
// }
|
||||
|
||||
// void SetTouchWebview(bool flag, bool force = false){
|
||||
// [[CustomView shared] setTouchWebview:flag forceCT:force];
|
||||
// }
|
||||
|
||||
// void ScrollWebview(float dx, float dy){
|
||||
// CGPoint pt = CGPointMake(dx, dy);
|
||||
// [[CustomView shared] scrollWebview:pt];
|
||||
// }
|
||||
|
||||
// void SetPadding(float left, float top, float right, float bottom){
|
||||
// [[CustomView shared] setWebviewPadding:CGRectMake(left, top, right, bottom)];
|
||||
// }
|
||||
|
||||
// void SetCTEnable(bool flag){
|
||||
// [[CustomView shared] enableCT:flag];
|
||||
// }
|
||||
void showGameA(bool flag){//显示游戏a
|
||||
[NativeUIManager showMainMenu];
|
||||
}
|
||||
void ShowH5View(bool flag){//设置显隐
|
||||
void ShowH5View(bool flag){//显示明或暗网页
|
||||
[[H5View shared] showView:flag];
|
||||
}
|
||||
void setInH5View(bool flag){//设置是否在h5界面
|
||||
[[H5View shared] setInH5View:flag];
|
||||
}
|
||||
|
||||
void OpenWebview(char* url) {//显示明网页
|
||||
[[H5View shared] showWebview:stringFromChar(url)];
|
||||
}
|
||||
void showDarkWebview() {//显示暗网页
|
||||
[[H5View shared] showDarkWebview:1];
|
||||
}
|
||||
void CloseWebview(){//隐藏
|
||||
[[H5View shared] hideWebview];
|
||||
}
|
||||
|
||||
void SetFullScreen(){
|
||||
[[H5View shared] setFullScreen];
|
||||
}
|
||||
|
||||
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 upDataH5times(char* weblink ,int times, bool is_dark){
|
||||
[[H5View shared] upDataH5times:weblink times:times is_dark:is_dark];
|
||||
}
|
||||
void SetPadding(float left, float top, float right, float bottom){
|
||||
[[H5View shared] setViewPadding:CGRectMake(left, top, right, bottom)];
|
||||
@@ -76,18 +20,11 @@ void upDataH5times(char* weblink ,int times, bool is_dark){
|
||||
void SetBtn(int left, int top, int right, int bottom){
|
||||
[[H5View shared] setViewBtn:CGRectMake(left, top, right, bottom)];
|
||||
}
|
||||
void SetCTEnable(bool flag){
|
||||
[[H5View shared] enableCT:flag];
|
||||
}
|
||||
|
||||
void SetIconProgress(float val){
|
||||
[[H5View shared] setIconProgress:val];
|
||||
}
|
||||
|
||||
void SetClickView(){
|
||||
[[H5View shared] setClickView];
|
||||
}
|
||||
|
||||
void ShowFlyBtn(bool show){
|
||||
[[H5View shared] showFlyBtn:show];
|
||||
}
|
||||
@@ -97,8 +34,9 @@ void SetBtn(int left, int top, int right, int bottom){
|
||||
void setRewardBtnTag (bool show) {
|
||||
[[H5View shared] setRewardBtnTag: show];
|
||||
}
|
||||
void SetOffset (int offset_y, int offset_y1) {
|
||||
[[H5View shared] SetOffset: offset_y offset_y1: offset_y1];
|
||||
}
|
||||
void OpenWv (bool show) {
|
||||
[[H5View shared] OpenWv];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -40,26 +40,7 @@ namespace DontConfuse
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
int time = 0;
|
||||
void Update()
|
||||
{
|
||||
if (Time.time > time)
|
||||
{
|
||||
H5sendClass info = new H5sendClass() { link = "www.baidu.com", type = "h6" };
|
||||
NetworkKit_sdk.PostWithHeader<object>("event/h5Impressions", info, (isSuccess, obj) =>
|
||||
{
|
||||
if (isSuccess)
|
||||
{
|
||||
Debug.Log("发送成功");
|
||||
Debug.Log(JsonConvert.SerializeObject(obj));
|
||||
|
||||
}
|
||||
});
|
||||
time++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
private void Awake()
|
||||
{
|
||||
// 当场景加载时,如果 _instance 还没赋值,就由挂载在物体上的自己来赋值
|
||||
|
||||
Reference in New Issue
Block a user