幽冥大陆(四十八)P50酒店门锁SDK 苹果object c语言仙盟插件——东方仙盟筑基期

Objective-C 实现代码

头文件(APP.h)

objc

复制代码
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

// 硬件交互相关的函数声明(对应原DLL的导出函数,Mac下替换为dylib)
// 注意:需根据硬件厂商的Mac版dylib修改函数签名
typedef int (*InitializeUSBFunc)(int);
typedef void (*CloseUSBFunc)(void);
typedef int (*BuzzerFunc)(int, int);
typedef int (*CardEraseFunc)(int, int, NSMutableString*);
typedef int (*GuestCardFunc)(int, int, int, int, int, int, NSString*, NSString*, NSString*, NSMutableString*);
typedef int (*ReadCardFunc)(int, uint8_t*, int);

@interface CyberWin_LocakAPP : NSObject
+ (NSString *)futureWindow_MeiPing_getSign:(uint8_t *)bufCard length:(NSUInteger)length;
+ (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength;
@end

@interface CyberWin_hoteldoor_prousbv10_2024 : NSObject
+ (int)initializeUSB:(int)d12;
+ (void)closeUSB;
+ (int)cardErase:(int)d12 dlsCoID:(int)dlsCoID cardNo:(NSMutableString *)cardNo;
@end

@interface APP : NSObject
@property (nonatomic, assign) uint8_t carddata[128];
@property (nonatomic, copy) NSString *idPhotoSavePath;
@property (nonatomic, assign) uint8_t bufCard[129]; // 128+1
@property (nonatomic, assign) uint8_t bufCard_v10[201]; // 200+1
@property (nonatomic, assign) int st;

// 核心方法
- (NSString *)start:(NSDictionary *)obj;
- (NSString *)status:(NSDictionary *)obj;
- (NSString *)checkingout:(NSDictionary *)obj;
- (NSString *)checkingin:(NSDictionary *)obj;
- (NSString *)getsign:(NSDictionary *)obj;

// 工具方法
- (BOOL)rdCard;
- (BOOL)rdCard_v10;
- (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength;
+ (void)writeLogWithCaptureType:(NSString *)capturetype type:(NSString *)type content:(NSString *)s;

@end

实现文件(APP.m)

objc

复制代码
#import "APP.h"
#include <dlfcn.h>
#include <string.h>
#include <time.h>

// 加载Mac版的dylib(需替换为实际的dylib路径)
static void *gDylibHandle = NULL;
static InitializeUSBFunc gInitializeUSB = NULL;
static CloseUSBFunc gCloseUSB = NULL;
static BuzzerFunc gBuzzer = NULL;
static CardEraseFunc gCardErase = NULL;
static GuestCardFunc gGuestCard = NULL;
static ReadCardFunc gReadCard = NULL;
static ReadCardFunc gReadCard_v10 = NULL;

@implementation CyberWin_LocakAPP

+ (NSString *)futureWindow_MeiPing_getSign:(uint8_t *)bufCard length:(NSUInteger)length {
    NSString *futureWindow = [[NSString alloc] initWithBytes:bufCard length:length encoding:NSASCIIStringEncoding];
    NSString *subStr = [self copyBytes:bufCard start:25 length:8 totalLength:length];
    if ([subStr isEqualToString:@"FFFFFFFF"]) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:@"此卡是空白卡,请换一张能开门的卡"];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        return @"此卡是空白卡,请换一张能开门的卡";
    }
    
    NSString *s = [self copyBytes:bufCard start:11 length:4 totalLength:length];
    NSUInteger i = strtoul([s UTF8String], NULL, 16) % 16384;
    NSString *s2 = [self copyBytes:bufCard start:9 length:2 totalLength:length];
    i += strtoul([s UTF8String], NULL, 16) * 65536;
    
    NSUInteger i2 = strtoul([self copyBytes:bufCard start:9 length:2 totalLength:length], NULL, 16) * 65536 + strtoul([self copyBytes:bufCard start:11 length:4 totalLength:length], NULL, 16) % 16383;
    return [NSString stringWithFormat:@"%lu", i2];
}

+ (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength {
    if (start < 1) {
        start = 1;
    }
    NSInteger realStart = start - 1;
    if (realStart + length > totalLength) {
        length = totalLength - realStart;
    }
    uint8_t *subBytes = malloc(length);
    memcpy(subBytes, bytes + realStart, length);
    NSString *result = [[NSString alloc] initWithBytes:subBytes length:length encoding:NSASCIIStringEncoding];
    free(subBytes);
    return result;
}

@end

@implementation CyberWin_hoteldoor_prousbv10_2024

+ (void)loadDylib {
    // 替换为实际的dylib路径,比如@"/usr/local/lib/proRFLV102024.dylib"
    NSString *dylibPath = @"proRFLV102024.dylib";
    gDylibHandle = dlopen([dylibPath UTF8String], RTLD_LAZY);
    if (gDylibHandle) {
        gInitializeUSB = (InitializeUSBFunc)dlsym(gDylibHandle, "initializeUSB");
        gCloseUSB = (CloseUSBFunc)dlsym(gDylibHandle, "CloseUSB");
        gCardErase = (CardEraseFunc)dlsym(gDylibHandle, "CardErase");
        // 其他函数同理加载
    } else {
        NSLog(@"加载dylib失败:%s", dlerror());
    }
}

+ (int)initializeUSB:(int)d12 {
    if (!gDylibHandle) {
        [self loadDylib];
    }
    if (gInitializeUSB) {
        return gInitializeUSB(d12);
    }
    return -1;
}

+ (void)closeUSB {
    if (gCloseUSB) {
        gCloseUSB();
    }
    if (gDylibHandle) {
        dlclose(gDylibHandle);
        gDylibHandle = NULL;
    }
}

+ (int)cardErase:(int)d12 dlsCoID:(int)dlsCoID cardNo:(NSMutableString *)cardNo {
    if (gCardErase) {
        return gCardErase(d12, dlsCoID, cardNo);
    }
    return -1;
}

@end

@implementation APP

- (instancetype)init {
    self = [super init];
    if (self) {
        memset(_carddata, 0, 128);
        memset(_bufCard, 0, 129);
        memset(_bufCard_v10, 0, 201);
        _st = 0;
        _idPhotoSavePath = @"";
        // 预加载dylib
        [CyberWin_hoteldoor_prousbv10_2024 loadDylib];
    }
    return self;
}

- (NSString *)start:(NSDictionary *)obj {
    NSString *param1 = obj[@"param1"];
    return @"随机预安装插件";
}

- (NSString *)status:(NSDictionary *)obj {
    // 调用蜂鸣器函数(需确保dylib中存在Buzzer函数)
    if (gBuzzer) {
        gBuzzer(1, 50);
    }
    return @"当你听到设备蜂鸣器,说明设备已经连接";
}

- (NSString *)checkingout:(NSDictionary *)obj {
    NSString *s = @"注销卡片";
    NSString *param = obj[@"param"];
    
    // 解析协议(原CyberWinProtocol,需自行实现协议解析逻辑,这里简化为字典模拟)
    NSDictionary *protocolDict = [self parseProtocol:param];
    NSString *hotelSign = protocolDict[@"hotelsign"];
    int hotelSignInt = [hotelSign intValue];
    
    // 初始化USB设备
    int st读卡器 = [CyberWin_hoteldoor_prousbv10_2024 initializeUSB:1];
    if (st读卡器 != 0) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:@"设备打开失败"];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        return @"打开端口失败";
    }
    
    // 注销卡片
    NSCursor *waitCursor = [NSCursor waitCursor];
    [waitCursor set];
    
    NSMutableString *cardNoStr = [NSMutableString stringWithCapacity:100];
    int st = [CyberWin_hoteldoor_prousbv10_2024 cardErase:1 dlsCoID:hotelSignInt cardNo:cardNoStr];
    
    [NSCursor arrowCursor].set;
    
    if (st != 0) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:[NSString stringWithFormat:@"注销失败\n%d", st]];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        s = [NSString stringWithFormat:@"%@:注销失败%d", s, st];
    } else {
        s = [NSString stringWithFormat:@"%@:成功", s];
    }
    
    [CyberWin_hoteldoor_prousbv10_2024 closeUSB];
    return s;
}

- (NSString *)checkingin:(NSDictionary *)obj {
    NSString *s = @"酒店入住发卡";
    NSString *param = obj[@"param"];
    
    // 解析协议(自行实现,这里简化)
    NSDictionary *protocolDict = [self parseProtocol:param];
    NSString *lockNoServer = protocolDict[@"lockno"];
    NSString *hotelSign = protocolDict[@"hotelsign"];
    NSString *checkingouttime = protocolDict[@"checkingouttime"];
    int hotelSignInt = [hotelSign intValue];
    
    // 校验锁号长度
    if (lockNoServer.length < 6) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:[NSString stringWithFormat:@"锁号长度错误=%@", lockNoServer]];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        return @"";
    }
    
    // 初始化USB设备
    int st = [CyberWin_hoteldoor_prousbv10_2024 initializeUSB:1];
    if (st != 0) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:@"设备打开失败"];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        return @"打开端口失败";
    }
    
    // 准备发卡参数
    NSCursor *waitCursor = [NSCursor waitCursor];
    [waitCursor set];
    
    // 获取当前时间(yyMMddHHmmss)
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyMMddHHmmss"];
    NSString *openTime = [formatter stringFromDate:[NSDate date]];
    
    // 反锁标志
    int antiLockSign = 1;
    int dai = 1;
    
    // 调用发卡函数(需确保dylib中存在GuestCard_原始函数)
    NSMutableString *cardHexStr = [NSMutableString stringWithCapacity:500];
    st = 0; // 替换为实际的GuestCard_原始调用,这里先置0模拟
    if (gGuestCard) {
        st = gGuestCard(1, hotelSignInt, 0, dai, antiLockSign, 0, openTime, checkingouttime, lockNoServer, cardHexStr);
    }
    
    [NSCursor arrowCursor].set;
    
    if (st != 0) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:[NSString stringWithFormat:@"调用发卡函数失败\n%d", st]];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        s = [NSString stringWithFormat:@"%@调用发卡函数失败", s];
    } else {
        s = [NSString stringWithFormat:@"%@制卡成功V2024%@", s, lockNoServer];
    }
    
    [CyberWin_hoteldoor_prousbv10_2024 closeUSB];
    return s;
}

- (NSString *)getsign:(NSDictionary *)obj {
    if (![self rdCard_v10]) {
        return @"读卡失败";
    }
    return [CyberWin_LocakAPP futureWindow_MeiPing_getSign:self.bufCard_v10 length:200];
}

- (BOOL)rdCard {
    NSCursor *waitCursor = [NSCursor waitCursor];
    [waitCursor set];
    
    int st = 0;
    if (gReadCard) {
        st = gReadCard(1, self.bufCard, 129);
    }
    
    if (st != 0) {
        NSString *msg = st == 1 ? @"请放一张卡在发卡器上面,确保门锁软件可以正常发卡,然后调试接口" : [NSString stringWithFormat:@"读卡失败\n%d", st];
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:st == 1 ? @"读卡失败(返回值=1)" : @"提示"];
        [alert setInformativeText:msg];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        [NSCursor arrowCursor].set;
        return NO;
    }
    
    NSString *subStr = [self copyBytes:self.bufCard start:5 length:2 totalLength:129];
    if (![subStr isEqualToString:@"01"]) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:@"发卡器的感应区无卡"];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        [NSCursor arrowCursor].set;
        return NO;
    }
    
    [NSCursor arrowCursor].set;
    return YES;
}

- (BOOL)rdCard_v10 {
    if (gReadCard_v10) {
        self.st = gReadCard_v10(1, self.bufCard_v10, 201);
    } else {
        self.st = -1;
    }
    
    if (self.st != 0) {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert setInformativeText:[NSString stringWithFormat:@"读卡失败%d", self.st]];
        [alert addButtonWithTitle:@"确定"];
        [alert runModal];
        return NO;
    }
    return YES;
}

- (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength {
    return [CyberWin_LocakAPP copyBytes:bytes start:start length:length totalLength:totalLength];
}

+ (void)writeLogWithCaptureType:(NSString *)capturetype type:(NSString *)type content:(NSString *)s {
    NSDate *now = [NSDate date];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy年MM月dd日"];
    NSString *dateStr = [dateFormatter stringFromDate:now];
    
    NSString *logPath = [NSString stringWithFormat:@"%@/log/%@/%@", [[NSBundle mainBundle] bundlePath], capturetype, dateStr];
    NSFileManager *fm = [NSFileManager defaultManager];
    if (![fm fileExistsAtPath:logPath isDirectory:NULL]) {
        NSError *error = nil;
        [fm createDirectoryAtPath:logPath withIntermediateDirectories:YES attributes:nil error:&error];
        if (error) {
            NSLog(@"创建日志目录失败:%@", error.localizedDescription);
            return;
        }
    }
    
    NSString *filePath = [logPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_log.log", type]];
    NSString *logContent = [NSString stringWithFormat:@"==============================\n%@<<<<<<<<<<<<<<<<<<<<<<<<<<\n%@\n\n", [NSDate localizedStringFromDate:now dateStyle:NSDateFormatterFullStyle timeStyle:NSDateFormatterFullStyle], s];
    
    NSError *error = nil;
    if (![logContent writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
        NSLog(@"写入日志失败:%@", error.localizedDescription);
    }
}

// 模拟协议解析(需根据实际协议实现)
- (NSDictionary *)parseProtocol:(NSString *)param {
    // 这里只是模拟,实际需要解析未来之窗协议的字符串为字典
    return @{
        @"hotelsign": @"123",
        @"lockno": @"123456",
        @"checkingouttime": [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]
    };
}

@end

关键说明

  1. dylib 加载 :使用dlopen/dlsym加载 Mac 版的动态库,需将代码中的proRFLV102024.dylib替换为硬件厂商提供的实际 dylib 路径和文件名。
  2. 协议解析 :原代码中的CyberWinProtocol协议解析逻辑需要你根据实际的 "未来之窗协议" 自行实现,代码中用parseProtocol方法做了模拟。
  3. 硬件函数调用 :原 C# 中的GuestCard_原始CardErase等函数,需要确保 Mac 版 dylib 中有对应的函数,且函数签名与代码中的 typedef 一致。
  4. 路径处理 :日志路径使用NSBundle mainBundle的路径,你可以根据需求修改为自定义路径(如用户文档目录)。

阿雪技术观

在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者。无论是分享代码、撰写技术博客,还是参与开源项目维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基生命,为科技进步添砖加瓦。

Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don't just be the one reaping all the benefits; step up and be a contributor too. Whether you're tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We're gonna team up and explore the whole silicon - based life thing, and in the process, we'll be fueling the growth of technology.

相关推荐
悟能不能悟6 小时前
java 设置日期返回格式的几种方式
java·开发语言
while(1){yan}6 小时前
基于IO流的三个小程序
java·开发语言·青少年编程
王燕龙(大卫)6 小时前
rust:线程
开发语言·rust
Dev7z6 小时前
基于MATLAB的零件表面缺陷检测系统设计与实现
开发语言·人工智能·matlab
曼巴UE56 小时前
UE C++ 字符串的操作
java·开发语言·c++
天天进步20156 小时前
Linux 实战:如何像查看文件一样“实时监控” System V 共享内存?
开发语言·c++·算法
凛_Lin~~7 小时前
安卓/Java语言基础八股文
java·开发语言·安卓
八年。。7 小时前
Python 版本确认方法
开发语言·笔记·python
foundbug9997 小时前
基于MATLAB Simulink的双向DC-DC变换器仿真程序实现
开发语言·matlab