添加皮肤

This commit is contained in:
2025-11-19 15:39:47 +08:00
parent 7518a29d2f
commit cc55bb107a
86 changed files with 17599 additions and 3467 deletions

View File

@@ -339,16 +339,18 @@
#if __has_include(<SSZipArchive/SSZipArchive.h>)
// zip_url Zip
//
// 1) 线 URLhttp/https KBNetworkManager
// 2) zip_url "bundle://" "bundle://001.zip"
if (!hasCachedAssets && zipURL.length > 0) {
dispatch_group_enter(group);
[[KBNetworkManager shared] GET:zipURL parameters:nil headers:nil completion:^(id jsonOrData, NSURLResponse *response, NSError *error) {
NSData *data = ([jsonOrData isKindOfClass:NSData.class] ? (NSData *)jsonOrData : nil);
if (error || data.length == 0) {
void (^handleZipData)(NSData *) = ^(NSData *data) {
if (data.length == 0) {
zipOK = NO;
dispatch_group_leave(group);
return;
}
// Zip
[[NSFileManager defaultManager] createDirectoryAtPath:skinRoot
withIntermediateDirectories:YES
@@ -370,9 +372,81 @@
[fm removeItemAtPath:zipPath error:nil];
if (!ok || unzipError) {
zipOK = NO;
dispatch_group_leave(group);
return;
}
//
// Skins/<skinId>/icons Skins/<skinId>/<>/icons
// icons background.png
BOOL isDir2 = NO;
NSArray *iconsContent = [fm contentsOfDirectoryAtPath:iconsDir error:NULL];
BOOL iconsValid = ([fm fileExistsAtPath:iconsDir isDirectory:&isDir2] && isDir2 && iconsContent.count > 0);
if (!iconsValid) {
NSArray<NSString *> *subItems = [fm contentsOfDirectoryAtPath:skinRoot error:NULL];
for (NSString *name in subItems) {
if ([name isEqualToString:@"icons"] || [name isEqualToString:@"__MACOSX"]) continue;
NSString *nestedRoot = [skinRoot stringByAppendingPathComponent:name];
BOOL isDirNested = NO;
if (![fm fileExistsAtPath:nestedRoot isDirectory:&isDirNested] || !isDirNested) continue;
NSString *nestedIcons = [nestedRoot stringByAppendingPathComponent:@"icons"];
BOOL isDirNestedIcons = NO;
if ([fm fileExistsAtPath:nestedIcons isDirectory:&isDirNestedIcons] && isDirNestedIcons) {
NSArray *nestedFiles = [fm contentsOfDirectoryAtPath:nestedIcons error:NULL];
if (nestedFiles.count > 0) {
// icons
[fm createDirectoryAtPath:iconsDir
withIntermediateDirectories:YES
attributes:nil
error:NULL];
// icons
for (NSString *fn in nestedFiles) {
NSString *from = [nestedIcons stringByAppendingPathComponent:fn];
NSString *to = [iconsDir stringByAppendingPathComponent:fn];
[fm removeItemAtPath:to error:nil];
[fm moveItemAtPath:from toPath:to error:nil];
}
}
}
// background.png skinRoot
NSString *nestedBg = [nestedRoot stringByAppendingPathComponent:@"background.png"];
if ([fm fileExistsAtPath:nestedBg]) {
[fm removeItemAtPath:bgPath error:nil];
[fm moveItemAtPath:nestedBg toPath:bgPath error:nil];
}
}
}
dispatch_group_leave(group);
}];
};
// bundle zip_url "bundle://001.zip"
if ([zipURL hasPrefix:@"bundle://"]) {
NSString *name = [zipURL substringFromIndex:@"bundle://".length];
NSString *fileName = name ?: @"";
NSString *ext = fileName.pathExtension;
NSString *base = fileName;
if (ext.length == 0) {
ext = @"zip";
} else {
base = [fileName stringByDeletingPathExtension];
}
NSString *path = [[NSBundle mainBundle] pathForResource:base ofType:ext];
NSData *data = (path.length > 0) ? [NSData dataWithContentsOfFile:path] : nil;
handleZipData(data);
} else {
//
[[KBNetworkManager shared] GET:zipURL parameters:nil headers:nil completion:^(id jsonOrData, NSURLResponse *response, NSError *error) {
NSData *data = ([jsonOrData isKindOfClass:NSData.class] ? (NSData *)jsonOrData : nil);
if (error || data.length == 0) {
zipOK = NO;
dispatch_group_leave(group);
return;
}
handleZipData(data);
}];
}
}
#else
zipOK = NO;