open source

This commit is contained in:
lvfulong
2020-11-11 16:17:13 +08:00
parent 4d989f3ecb
commit bc4ca748de
2441 changed files with 623057 additions and 2 deletions
@@ -0,0 +1,54 @@
#import <UIKit/UIKit.h>
//文字相关的函数
//-----------------------------------------------------------------
void CToObjectCLog( const char* szFormat,...)
{
va_list args;
va_start(args, szFormat);
NSString* nsFormat = [NSString stringWithUTF8String:szFormat];
NSLogv( nsFormat, args);
va_end(args);
}
void CToObjectCLogI( const char* szFormat,...)
{
va_list args;
va_start(args, szFormat);
NSString* nsFormat = [NSString stringWithUTF8String:szFormat];
NSLogv( nsFormat, args);
va_end(args);
}
void CToObjectCLogE( const char* szFormat,...)
{
va_list args;
va_start(args, szFormat);
NSString* nsFormat = [NSString stringWithUTF8String:szFormat];
NSLogv( nsFormat, args);
va_end(args);
}
void CToObjectCLogW( const char* szFormat,...)
{
va_list args;
va_start(args, szFormat);
NSString* nsFormat = [NSString stringWithUTF8String:szFormat];
NSLogv( nsFormat, args);
va_end(args);
}
void alert(const char* fmt, ...)
{
char buf[1024];
char* pBuf = NULL;
va_list args;
va_start(args, fmt);
int len = vsprintf(buf, fmt, args);
if (len < 0) {
pBuf = new char[4096];
len = vsprintf(pBuf, fmt, args);
}
va_end(args);
CToObjectCLog(pBuf ? pBuf : buf);
if (pBuf)
{
delete[] pBuf;
}
}
@@ -0,0 +1,115 @@
#include "LayaCacheManager.h"
#include "resource/JCFileResManager.h"
#include "downloadCache/JCServerFileCache.h"
#include "downloadMgr/JCDownloadMgr.h"
#include "misc/JCWorkerThread.h"
#include <cmath>
std::string gAssetRootPath = "";
std::string gRedistPath = "";
namespace laya {
LayaCacheManager* LayaCacheManager::m_pInstance = nullptr;
LayaCacheManager::LayaCacheManager()
{
m_pSvFileCache = nullptr;
pthread_key_create(&JCWorkerThread::s_tls_curThread, NULL);
pthread_key_create(&s_tls_curDataThread, NULL);
JCDownloadMgr::getInstance()->init(3);//多加一个线程,可能要给优先级较低的任务用。
m_pFileResMgr = new JCFileResManager(JCDownloadMgr::getInstance());
m_CallbackRef.reset(new int(1));
}
LayaCacheManager::~LayaCacheManager()
{
}
LayaCacheManager* LayaCacheManager::getInstance(){
if( m_pInstance == NULL){
m_pInstance = new LayaCacheManager();
}
return m_pInstance;
}
void LayaCacheManager::delInstance(){
if(m_pInstance){
delete m_pInstance;
m_pInstance = NULL;
}
}
std::string LayaCacheManager::preUpdateDcc(const std::string& redistPath,const std::string& domain)
{
if (m_pSvFileCache != nullptr){
delete m_pSvFileCache;
}
m_pSvFileCache = new laya::JCServerFileCache();
m_pFileResMgr->setFileCache(m_pSvFileCache);
m_pSvFileCache->setCachePath((redistPath + "appCache").c_str());
m_pSvFileCache->switchToApp(domain.c_str());
m_pSvFileCache->setResourceID("appurl", domain.c_str());
return m_pSvFileCache->getResourceID("netassetsid");
}
void LayaCacheManager::updateDccClearAssetsid(const std::string& redistPath,const std::string& domain)
{
m_pSvFileCache->saveFileTable("");
m_pSvFileCache->setResourceID("netassetsid", "");
if (m_pSvFileCache != nullptr){
delete m_pSvFileCache;
}
m_pSvFileCache = new laya::JCServerFileCache();
m_pFileResMgr->setFileCache(m_pSvFileCache);
m_pSvFileCache->setCachePath((redistPath + "appCache").c_str());
m_pSvFileCache->switchToApp(domain.c_str());
}
void LayaCacheManager::doUpdateDcc(const std::string& redistPath,const std::string& domain,const std::string& txtdcc,const std::string& assetsid)
{
m_pSvFileCache->saveFileTable(txtdcc.c_str());
if (m_pSvFileCache != nullptr){
delete m_pSvFileCache;
}
m_pSvFileCache = new laya::JCServerFileCache();
m_pFileResMgr->setFileCache(m_pSvFileCache);
m_pSvFileCache->setCachePath((redistPath + "appCache").c_str());
m_pSvFileCache->switchToApp(domain.c_str());
m_pSvFileCache->setResourceID("netassetsid", assetsid.c_str());
}
void LayaCacheManager::handleRequest(const char* strUrl, std::function<void(void* pData, int length)> onDownload, std::function<void(int errCode)> onError)
{
laya::JCFileRes* pRes = m_pFileResMgr->getRes(strUrl);
std::weak_ptr<int> cbref(m_CallbackRef);
pRes->setOnReadyCB(std::bind(&LayaCacheManager::onDownloadEnd,this, std::placeholders::_1, cbref, onDownload));
pRes->setOnErrorCB(std::bind(&LayaCacheManager::onDownloadErr, this, std::placeholders::_1, std::placeholders::_2, cbref, onError));
}
bool LayaCacheManager::onDownloadErr(void* p_pRes, int p_nErrCode,std::weak_ptr<int> callbackref, std::function<void(int errCode)> onError)
{
if (!callbackref.lock())
return false;
onError(p_nErrCode);
return true;
}
bool LayaCacheManager::onDownloadEnd(void* p_pRes, std::weak_ptr<int> callbackref, std::function<void(void* pData, int length)> onDownload)
{
if( !callbackref.lock() )
return false;
laya::JCResStateDispatcher* pRes = (laya::JCResStateDispatcher*)p_pRes;
laya::JCFileRes* pFileRes = (laya::JCFileRes*)pRes;
if( pFileRes->m_pBuffer.get()==NULL || pFileRes->m_nLength==0 ){
return false;
}
onDownload(pFileRes->m_pBuffer.get(), pFileRes->m_nLength);
return true;
}
}
@@ -0,0 +1,34 @@
#ifndef LayaCacheManager_hpp
#define LayaCacheManager_hpp
#include <string>
#include <stdio.h>
#include <functional>
namespace laya {
class JCFileResManager;
class JCServerFileCache;
class JCFileRes;
class LayaCacheManager
{
public:
LayaCacheManager();
virtual ~LayaCacheManager();
static LayaCacheManager* getInstance();
static void delInstance();
void handleRequest(const char* strUrl, std::function<void(void* pData, int length)> onDownload, std::function<void(int errCode)> onError);
bool onDownloadErr(void* p_pRes, int p_nErrCode,std::weak_ptr<int> callbackref, std::function<void(int errCode)> onError);
bool onDownloadEnd(void* p_pRes, std::weak_ptr<int> callbackref, std::function<void(void* pData, int length)> onDownload);
std::string preUpdateDcc(const std::string& redistPath,const std::string& domain);
void updateDccClearAssetsid(const std::string& redistPath,const std::string& domain);
void doUpdateDcc(const std::string& redistPath,const std::string& domain,const std::string& txtdcc,const std::string& assetsid);
protected:
JCFileResManager* m_pFileResMgr;
JCServerFileCache* m_pSvFileCache;
static LayaCacheManager* m_pInstance;
std::shared_ptr<int> m_CallbackRef;
};
}
#endif /* LayaCacheManager_hpp */
@@ -0,0 +1,28 @@
//
// LayaWKWebview.h
// LayaWKWebview
//
// Created by helloworldlv on 2018/3/23.
// Copyright © 2018年 render. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
#import <WebKit/WKWebview.h>
#import <WebKit/WKUserContentController.h>
#import <WebKit/WKUserScript.h>
@interface LayaWKWebview : NSObject
@property(nonatomic, strong) WKWebView* webview;
/*接管下载,支持DCC*/
- (instancetype)initWithWebview:(WKWebView*)webview url:(NSString*)url hostPort:(int)port;
/*直接调WKWebview,不支持DCC*/
- (instancetype)initWithWebview:(WKWebView*)webview url:(NSString*)url;
- (void)loadUrl:(NSString*)url;
- (NSString*)callMethod:(int)objid className:(NSString*)cls methodName:(NSString*)method param:(NSString*)param;
-(void)callbackToJSWithClass:(Class)cls methodName:(NSString*)name ret:(NSObject*)retObj;
-(void)callbackToJSWithClassName:(NSString*)cls methodName:(NSString*)name ret:(NSObject*)retObj;
-(void)callbackToJSWithObject:(id)obj methodName:(NSString*)name ret:(NSObject*)retObj;
-(void)runJS:(NSString*)script;
+(LayaWKWebview*)GetLayaWKWebview;
@end
@@ -0,0 +1,325 @@
//
// LayaWKWebview.m
// LayaWKWebview
//
// Created by helloworldlv on 2018/3/23.
// Copyright © 2018年 render. All rights reserved.
//
#import "LayaWKWebview.h"
#import "GCDWebServer.h"
#import "GCDWebServerDataResponse.h"
#import "GCDWebServerFunctions.h"
#import "refection.h"
#include <string>
#include "LayaCache/LayaCacheManager.h"
extern std::string gRedistPath;
extern std::string gAssetRootPath;
static LayaWKWebview* g_pLayaWKWebview = nil;
@implementation LayaWKWebview
{
NSString* _url;
int _hostPort;
GCDWebServer* _GCDWebServer;
Reflection* _reflection;
NSString* _urlSuffix;
}
+(LayaWKWebview*)GetLayaWKWebview
{
return g_pLayaWKWebview;
}
- (instancetype)initWithWebview:(WKWebView*)webview url:(NSString*)url
{
if ((self = [super init]))
{
g_pLayaWKWebview = self;
_webview = webview;
_url = url;
_hostPort = 0;
NSURL* pUrl = [NSURL URLWithString:url];
NSURLRequest* pUrlRequest = [NSURLRequest requestWithURL:pUrl];
[_webview loadRequest:pUrlRequest];
_reflection = [[Reflection alloc]init:self];
_urlSuffix = nil;
}
return self;
}
- (instancetype)initWithWebview:(WKWebView*)webview url:(NSString*)url hostPort:(int)port;
{
if ((self = [super init]))
{
g_pLayaWKWebview = self;
_reflection = [[Reflection alloc]init:self];
_webview = webview;
_url = url;
_hostPort = port;
if ([url isEqual:@"http://stand.alone.version/index.html"] || [url isEqual:@"http://stand.alone.version/index.js"])
{
gRedistPath = [[self getRootCachePath] cStringUsingEncoding:NSUTF8StringEncoding];
gAssetRootPath= [[self getResourcePath] cStringUsingEncoding:NSUTF8StringEncoding];
gAssetRootPath += "/cache/";
NSString* urlpath = [self getLaunchUrlDomain:url];
NSLog(@"[dcc] [%@]",url);
laya::LayaCacheManager::getInstance()->preUpdateDcc(gRedistPath,urlpath.UTF8String);
[self requestGame:url];
}
else
{
[self updateDcc:_url];
}
}
return self;
}
-(NSString *)convertDataToHexStr:(NSData *)data
{
if (!data || [data length] == 0)
{
return @"";
}
NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
[data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop)
{
unsigned char *dataBytes = (unsigned char*)bytes;
for (NSInteger i = byteRange.length - 1; i >=0 ; i--)
{
NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
if ([hexStr length] == 2)
{
[string appendString:hexStr];
} else
{
[string appendFormat:@"0%@", hexStr];
}
}
}];
return string;
}
-(NSString*)getLaunchUrlDomain:(NSString*)url
{
NSString* domain = [[NSString alloc] initWithString:url];
domain = [domain stringByReplacingOccurrencesOfString:@"?" withString:@""];
domain = [[NSURL alloc] initWithString:domain].URLByDeletingLastPathComponent.absoluteString;
return domain;
}
-(NSString*)getLayaBoxUrl
{
return [NSString stringWithFormat:@"http://127.0.0.1:%lu/s/%@", (unsigned long)(_GCDWebServer.port),_url];
}
-(NSString*) getResourcePath
{
return [[NSBundle mainBundle] resourcePath];
}
-(NSString*) getRootCachePath
{
NSString* sAppDirctory = NSHomeDirectory();
NSString* sDownloadRootPath = [ NSString stringWithFormat: @"%@/Library/Caches/", sAppDirctory ];
return sDownloadRootPath;
}
- (void)updateDcc:(NSString*)url
{
gRedistPath = [[self getRootCachePath] cStringUsingEncoding:NSUTF8StringEncoding];
gAssetRootPath= [[self getResourcePath] cStringUsingEncoding:NSUTF8StringEncoding];
gAssetRootPath += "/cache/";
NSLog(@"[dcc] update dcc start [%@] ...",url);
NSString* urlpath = [self getLaunchUrlDomain:url];
/*NSString* urlpath = [[NSString alloc] initWithString:url];
urlpath = [urlpath stringByReplacingOccurrencesOfString:@"?" withString:@""];
urlpath = [[NSURL alloc] initWithString:urlpath].URLByDeletingLastPathComponent.absoluteString;*/
NSLog(@"[dcc] [%@]",url);
std::string curassets = laya::LayaCacheManager::getInstance()->preUpdateDcc(gRedistPath,urlpath.UTF8String);
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
NSString* asidUrl = [[NSString alloc] initWithFormat:@"%@update/assetsid.txt?rand=%f",urlpath,(rand()/(float)RAND_MAX) * [NSDate date].timeIntervalSince1970];
NSLog(@"[dcc] %@",asidUrl);
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:asidUrl] completionHandler:^(NSData * data, NSURLResponse * response, NSError * error)
{
NSLog(@"[dcc] assetsid.txt download complete");
NSString* assetsidStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (error || (assetsidStr == nil) || [assetsidStr isEqualToString:@""])
{
if (error)
{
NSLog(@"[dcc] assetsid.txt download error [%@] [%@] [%@]",error.localizedFailureReason,error.localizedDescription,error.localizedRecoverySuggestion);
}
laya::LayaCacheManager::getInstance()->updateDccClearAssetsid(gRedistPath,urlpath.UTF8String);
[self requestGame:url];
}
else
{
if ([assetsidStr UTF8String] != curassets)
{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
NSString* asidUrl = [[NSString alloc] initWithFormat:@"%@update/filetable.bin?%@",urlpath,assetsidStr];
NSLog(@"[dcc] %@", asidUrl);
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:asidUrl] completionHandler:^(NSData * data, NSURLResponse * response, NSError * error)
{
NSMutableString* txtdcc = [[NSMutableString alloc]init];
NSLog(@"[dcc] filetable.bin download complete");
if (error)
{
NSLog(@"[dcc] filetable.bin download error");
}
if (data == nil || data.length % 8 != 0)
{
NSLog(@"[dcc] filetable.bin length error");
}
else
{
int32_t* v = (int32_t*)data.bytes;
if (v[0] != 0xffeeddcc || v[1] != 1)
{
NSLog(@"dcc.bin file err!");
}
else
{
if (v[2] == 0x00ffffff)
{
int stp = (4 + 8) / 2;
NSData* md5 = [data subdataWithRange:NSMakeRange(4*4, 8*4)];
NSString* so = [[NSString alloc] initWithData:md5 encoding:NSUTF8StringEncoding];
NSLog(@"--------------------------------------------");
NSLog(@"so=%@",so);
NSLog(@"netid=%@",assetsidStr);
if ([so isEqualToString:assetsidStr])
{
for (NSUInteger ii = stp, isz = data.length / (2*4); ii < isz; ii++)
{
NSData* data1 = [data subdataWithRange:NSMakeRange(ii * 2 * 4, 4)];
NSData* data2 = [data subdataWithRange:NSMakeRange(ii * 2 * 4 + 4, 4)];
NSString* dccstr = [[NSString alloc] initWithFormat:@"%@ %@\n",[self convertDataToHexStr:data1],[self convertDataToHexStr:data2]];
[txtdcc appendString:dccstr];
}
}
}
else
{
NSLog(@"error old format unsupport");
}
}
}
if ([txtdcc length] > 0)
{
laya::LayaCacheManager::getInstance()->doUpdateDcc(gRedistPath,urlpath.UTF8String,txtdcc.UTF8String,assetsidStr.UTF8String);
}
else
{
}
[self requestGame:url];
}];
[task resume];
}
else
{
[self requestGame:url];
}
}
}];
[task resume];
}
-(void)requestGame:(NSString*)url
{
NSURL* nsurl = [[NSURL alloc] initWithString:url];
NSString* caturl = nil;
if (nsurl.port)
{
caturl = [[NSString alloc] initWithFormat:@"%@://%@:%@",nsurl.scheme, nsurl.host, nsurl.port];
}
else
{
caturl = [[NSString alloc] initWithFormat:@"%@://%@",nsurl.scheme, nsurl.host];
}
NSLog(@"%@", caturl);
// Create server
_GCDWebServer = [[GCDWebServer alloc] init];
// Add a handler to respond to GET requests on any URL
[_GCDWebServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
NSString* urlOCStr = nil;
if (![request.path hasPrefix:@"/s"]) {
urlOCStr =[[NSString alloc] initWithFormat:@"%@%@",caturl, request.URL.resourceSpecifier];
//TODO 没考虑
}
else {
urlOCStr = [request.URL.absoluteString stringByReplacingOccurrencesOfString:_urlSuffix withString:@""];
}
if ([urlOCStr containsString:@"http://stand.alone.version/"])
{
NSURL* tempUrl = [NSURL URLWithString:urlOCStr];
if (tempUrl.query && ![tempUrl.query isEqualToString:@""] )
{
urlOCStr = [urlOCStr stringByReplacingOccurrencesOfString:[[NSString alloc] initWithFormat:@"?%@", tempUrl.query] withString:@""];
}
}
NSString* contentType = GCDWebServerGetMimeTypeForExtension([[request path] pathExtension], nil);
const char* pURL = urlOCStr.UTF8String;
laya::LayaCacheManager::getInstance()->handleRequest(pURL, [contentType,completionBlock,request](void* pData, int length) {
NSData *data = [[NSData alloc] initWithBytes:pData length:length];
GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithData:data contentType:contentType];
completionBlock(response);
},[completionBlock](int errCode){
//NSLog(@"dowlonad error [%d]",errCode);
completionBlock(nil);
});
}];
NSError *error = nil;
int httpPort = (_hostPort != 0) ? _hostPort :12344;
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:GCDWebServerOption_BindToLocalhost];
[options setObject:@"GCD Web Server" forKey:GCDWebServerOption_ServerName];
do {
NSLog(@"Starting http daemon port %d",httpPort);
[options setObject:[NSNumber numberWithInteger:httpPort++] forKey:GCDWebServerOption_Port];
} while(![_GCDWebServer startWithOptions:options error:&error]);
if (error) {
NSLog(@"Error starting http daemon: %@", error);
} else {
//[_GCDWebServer setLogLevel:kGCDWebServerLoggingLevel_Warning];
NSLog(@"Started http daemon port %lu",(unsigned long)_GCDWebServer.port);
}
[self loadUrl:[self getLayaBoxUrl]];
_urlSuffix = [NSString stringWithFormat:@"http://127.0.0.1:%lu/s/", (unsigned long)(_GCDWebServer.port)];
}
- (void)loadUrl:(NSString*)url
{
NSURL* pUrl = [NSURL URLWithString:url ];
NSURLRequest* pUrlRequest = [NSURLRequest requestWithURL:pUrl];
[_webview loadRequest:pUrlRequest];
}
- (NSString*)callMethod:(int)objid className:(NSString*)cls methodName:(NSString*)method param:(NSString*)param
{
return [_reflection callMethod:objid className:cls methodName:method param:param];
}
-(void)callbackToJSWithClass:(Class)cls methodName:(NSString*)name ret:(NSObject*)retObj
{
[_reflection callbackToJSWithClass:cls methodName:name ret:retObj];
}
-(void)callbackToJSWithClassName:(NSString*)cls methodName:(NSString*)name ret:(NSObject*)retObj
{
[_reflection callbackToJSWithClassName:cls methodName:name ret:retObj];
}
-(void)callbackToJSWithObject:(id)obj methodName:(NSString*)name ret:(NSObject*)retObj
{
[_reflection callbackToJSWithObject:obj methodName:name ret:retObj];
}
-(void)runJS:(NSString*)script
{
[self.webview evaluateJavaScript:script completionHandler:^(id _Nullable response, NSError * _Nullable error) {
if (response || error)
{
NSLog(@"value: %@ error: %@", response, error);
}
}];
}
@end
@@ -0,0 +1,38 @@
/**
@file conchConfig.h
@brief 配置用到的,比如版本号 或者描述信息
@author James
@version 1.0
@date 2013_7_5
@company LayaBox
*/
#import "UIKit/UIKit.h"
#import <GLKit/GLKit.h>
#import <string>
@interface conchConfig : NSObject
{
@public
NSString* m_sAppVersion; //对外版本号
NSString* m_sAppLocalVersion; //对内版本号
NSString* m_sLaya8Url; //如果是Laya8启动,启动的url
std::string m_sBackgroundcolor; //背景色
NSString* m_sGameID; //appStroe用到的
bool m_bCheckNetwork; //是否检查网络
bool m_bNotification; //是否打开推送
bool m_bShowAssistantTouch; //是否显示AssitantTouch
/*
UIInterfaceOrientationMaskPortrait, ===2
UIInterfaceOrientationMaskPortraitUpsideDown, ===4
UIInterfaceOrientationMaskLandscapeLeft, ===8
UIInterfaceOrientationMaskLandscapeRight, ===16
*/
int m_nOrientationType; //游戏的方向
NSString* m_sUrl; //游戏url
int m_nHostPort; //hostPort
}
+(conchConfig*)GetInstance;
-(bool)readIni;
-(conchConfig*)init;
@end
@@ -0,0 +1,152 @@
/**
@file conchConfig.h
@brief 配置用到的,比如版本号 或者描述信息
@author wyw
@version 1.0
@date 2013_7_5
@company JoyChina
*/
#import "conchConfig.h"
#import <util/JCIniFile.h>
#import <string>
//-------------------------------------------------------------------------------
static conchConfig* g_pConchConfig = nil;
//-------------------------------------------------------------------------------
@implementation conchConfig
//-------------------------------------------------------------------------------
+(conchConfig*)GetInstance
{
if( g_pConchConfig == nil )
{
g_pConchConfig = [[conchConfig alloc] init];
}
return g_pConchConfig;
}
//-------------------------------------------------------------------------------
-(conchConfig*)init
{
self = [super init];
m_sLaya8Url=nil; //如果是Laya8启动,启动的url
m_sBackgroundcolor="#FFFFFF";//背景色
m_sGameID=nil; //appStroe用到的
m_bCheckNetwork=true; //是否检查网络
m_bNotification=false; //是否打开消息推送
m_nOrientationType = 30; //屏幕的方向
m_sUrl=nil;
m_nHostPort=0;
m_bShowAssistantTouch = false;
[self readIni];
m_sAppVersion=nil; //版本号
m_sAppLocalVersion = nil; //对内版本号
NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
// 当前应用软件版本 Bundle versions string, short
m_sAppVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
NSLog(@"当前应用软件版本:%@",m_sAppVersion);
// 当前应用版本号码 Bundle versions
m_sAppLocalVersion = [infoDictionary objectForKey:@"CFBundleVersion"];
NSLog(@"当前应用Local版本号码:%@",m_sAppLocalVersion);
return self;
}
//-------------------------------------------------------------------------------
-(bool) readIni
{
std::string sIniFileName = [[self getResourcePath] cStringUsingEncoding:NSUTF8StringEncoding];
sIniFileName += "/config.ini";
// 初始化 IAP
laya::JCIniFile *pConfigFile = laya::JCIniFile::loadFile( sIniFileName.c_str() );
if( 0 == pConfigFile )
{
return false;
}
else
{
const char* sGameID=pConfigFile->GetValue("gameID");
const char* sBackgroundColor=pConfigFile->GetValue("backgroundColor");
const char* sCheckNetwork=pConfigFile->GetValue("checkNetwork");
const char* sOrientation=pConfigFile->GetValue("orientation");
const char* sHostPort = pConfigFile->GetValue("hostport");
const char* sUrl = pConfigFile->GetValue("url");
const char* sNotification = pConfigFile->GetValue("notification");
const char* sAssistantTouch = pConfigFile->GetValue("assistantTouch");
if( sGameID )
{
m_sGameID = [[NSString alloc] initWithUTF8String:sGameID ];
}
else
{
NSLog(@"读取ini gameID 错误");
}
if( sBackgroundColor )
{
m_sBackgroundcolor = sBackgroundColor;
}
else
{
NSLog(@"读取ini backgroundColor 错误");
}
if( sCheckNetwork )
{
m_bCheckNetwork = atoi(sCheckNetwork)>0;
}
else
{
NSLog(@"读取ini checkNetworkd 错误");
}
if( sOrientation )
{
m_nOrientationType = atoi(sOrientation);
if( m_nOrientationType < 1 )
{
NSLog(@"读取ini orientation 错误");
}
}
else
{
NSLog(@"读取ini orientation错误");
}
if( sHostPort )
{
m_nHostPort = atoi(sHostPort);
}
else
{
NSLog(@"读取ini hostport错误");
}
if( sUrl )
{
m_sUrl = [[NSString alloc]initWithUTF8String:sUrl];
}
else
{
NSLog(@"读取ini url错误");
}
if( sNotification )
{
m_bNotification = atoi(sNotification)>0;
}
else
{
NSLog(@"读取ini notification 错误");
}
if( sAssistantTouch )
{
m_bShowAssistantTouch = atoi(sAssistantTouch)>0;
}
else
{
NSLog(@"读取ini assistantTouch 错误");
}
delete pConfigFile;
pConfigFile = NULL;
}
return true;
}
//------------------------------------------------------------------------------
-(NSString*) getResourcePath
{
return [[NSBundle mainBundle] resourcePath];
}
@end
@@ -0,0 +1,23 @@
/**
@file
@brief
@author
@version 1.0
@date
@company LayaBox
*/
#import <objc/NSObject.h>
#import <objc/objc.h>
#import <Foundation/NSString.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSInvocation.h>
#import "LayaWKWebview.h"
@interface Reflection : NSObject
-(id)init:(LayaWKWebview*)webview;
-(void)clearReflectionObjects;
-(NSString*)callMethod:(int)objid className:(NSString*)cls methodName:(NSString*)method param:(NSString*)param;
-(void)callbackToJSWithClass:(Class)cls methodName:(NSString*)name ret:(NSObject*)retObj;
-(void)callbackToJSWithClassName:(NSString*)cls methodName:(NSString*)name ret:(NSObject*)retObj;
-(void)callbackToJSWithObject:(id)obj methodName:(NSString*)name ret:(NSObject*)retObj;
@end
@@ -0,0 +1,221 @@
#import "refection.h"
#import <Foundation/Foundation.h>
#include <string>
//#import "../../../../source/conch/CToObjectC.h"
//#import "CToObjectCIOS.h"
//#import "../../../../../source/conch/JCScriptRuntime.h"
//#import "JCThreadCmdMgr.h"
extern void reflectionCallback(const std::string& jsonret);
@implementation Reflection
{
NSMutableDictionary* m_pIDToObjectDic;
NSMutableDictionary* m_pObjectToIDDic;
NSLock* m_lock;
LayaWKWebview* m_webview;
}
-(id)init:(LayaWKWebview*)webview;
{
self = [super init];
if( self != nil )
{
m_webview = webview;
m_pIDToObjectDic = [NSMutableDictionary dictionary];
m_pObjectToIDDic = [NSMutableDictionary dictionary];
m_lock = [NSLock new];
return self;
}
return nil;
}
-(void)clearReflectionObjects
{
[m_lock lock];
[m_pIDToObjectDic removeAllObjects];
[m_pObjectToIDDic removeAllObjects];
[m_lock unlock];
}
-(NSString*)invoke: (Class) objc_class isStatic:(BOOL) isStatic target:(id)target select:(SEL)select Param:(NSString*)param
{
NSMethodSignature* signature = isStatic ? [objc_class methodSignatureForSelector:select] : [objc_class instanceMethodSignatureForSelector:select];
if (signature == nil){
NSLog(@"reflection error: can not find method signature");
return @"{}";
}
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
if (invocation == nil){
NSLog(@"reflection error: can not find invocation");
return @"{}";
}
[invocation setTarget:target];
[invocation setSelector:select];
NSUInteger numArgs = [signature numberOfArguments];
NSData* jsonData = [param dataUsingEncoding:NSUTF8StringEncoding];
if (jsonData == nil){
NSLog(@"reflection error");
return @"{}";
}
NSError* error = nil;
id idPara = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
if (idPara == nil || ![idPara isKindOfClass:[NSArray class]]){
NSLog(@"reflection error");
return @"{}";
}
NSArray* paraArray = idPara;
NSUInteger num = [paraArray count];
if (numArgs != num + 2){
NSLog(@"reflection error: argument number is [%lu] but need [%lu]",(unsigned long)num,(unsigned long)(numArgs-2));
return @"{}";
}
for(int i = 2; i < num + 2; i++){
NSObject* obj = [paraArray objectAtIndex:i-2];
[invocation setArgument:&obj atIndex:i];
}
[invocation invoke];
if (!strcmp(signature.methodReturnType, @encode(void))) {
return @"{}";
}
const char* methodReturnType = signature.methodReturnType;
if (!strcmp(methodReturnType, "@")) {
NSLog(@"method return type %s",methodReturnType);
id returnValue;
[invocation getReturnValue:&returnValue];
NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:returnValue, @"v",nil];
NSError* pError = nil;
NSData* pJsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&pError];
if (pError) {
NSLog(@"%@ %@", pError.debugDescription, pError.description);
return @"{}";
}
return [[NSString alloc] initWithData:pJsonData encoding:NSUTF8StringEncoding];
}
else {
NSLog(@"method return type %s not supported",methodReturnType);
return @"{}";
}
return @"{}";
}
-(NSString*)callMethod:(int)objid className:(NSString*)cls methodName:(NSString*)method param:(NSString*)param
{
Class objc_class = NSClassFromString(cls);
if (objc_class == nil){
NSLog(@"reflection error : can not find class [%@]",cls);
return @"{}";
}
if (objid == -1){
SEL select = NSSelectorFromString(method);
if (select == 0){
NSLog(@"reflection error");
return @"{}";
}
return [self invoke:objc_class isStatic:TRUE target:objc_class select:select Param:param];
}
else{
if ([method isEqualToString:@"<init>"]){//构造函数
NSObject* object = [[objc_class alloc] init];
if (object == nil){
NSLog(@"reflection error : alloc init class [%@] object failed",cls);
return @"{}";
}
[m_lock lock];
[m_pIDToObjectDic setObject:object forKey:[NSNumber numberWithInt:objid]];
[m_pObjectToIDDic setObject:[NSNumber numberWithInt:objid] forKey:[NSNumber numberWithInteger:(NSInteger)object]];
[m_lock unlock];
}
else{
NSObject* object = [m_pIDToObjectDic objectForKey:[NSNumber numberWithInt:objid]];
if (object == nil){
NSLog(@"reflection error : can not find object id [%i]",objid);
return @"{}";
}
if (![object isKindOfClass:objc_class]){
NSLog(@"reflection error : object of id [%i] is not king of class [%@]",objid,cls);
return @"{}";
}
SEL select = NSSelectorFromString(method);
if (select == 0){
NSLog(@"reflection error");
return @"{}";
}
return [self invoke:objc_class isStatic:FALSE target:object select:select Param:param];
}
}
return @"{}";
}
-(void)callbackToJSWithClass:(Class)cls methodName:(NSString*)name ret:(NSObject*)retObj
{
[self callbackToJSWithClassName:NSStringFromClass(cls) methodName:name ret:retObj];
}
-(void)callbackToJSWithClassName:(NSString*)cls methodName:(NSString*)name ret:(NSObject*)retObj
{
NSMutableDictionary* dic = [NSMutableDictionary dictionary];
[dic setObject:@-1 forKey:@"objId"];
[dic setObject:cls forKey:@"cName"];
[dic setObject:name forKey:@"mName"];
if (retObj == nil)
[dic setObject:@"" forKey:@"v"];
else
[dic setObject:retObj forKey:@"v"];
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&error];
if (error != nil){
NSLog(@"callbackToJS error");
return;
}
NSString* jason = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString* js = [NSString stringWithFormat:@"window.conchPlatCallBack(%@)", jason];
js = [[js stringByReplacingOccurrencesOfString:@"\n" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
[m_webview runJS:js];
NSLog(@"run js: %@", js);
}
-(void)callbackToJSWithObject:(id)obj methodName:(NSString*)name ret:(NSObject*)retObj
{
NSMutableDictionary* dic = [NSMutableDictionary dictionary];
[m_lock lock];
[dic setObject:[m_pObjectToIDDic objectForKey:[NSNumber numberWithInteger:(NSInteger)obj]] forKey:@"objId"];
[m_lock unlock];
[dic setObject:@"" forKey:@"cName"];
[dic setObject:name forKey:@"mName"];
if (retObj == nil)
[dic setObject:@"" forKey:@"v"];
else
[dic setObject:retObj forKey:@"v"];
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&error];
if (error != nil){
NSLog(@"callbackToJS error");
return;
}
NSString* jason = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString* js = [NSString stringWithFormat:@"window.conchPlatCallBack(%@)", jason];
js = [[js stringByReplacingOccurrencesOfString:@"\n" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
[m_webview runJS:js];
NSLog(@"run js: %@", js);
}
@end