当前位置: 首页 > news >正文

Unity3D与iOS的交互 简单版开箱即用

本文适合的情况如下:

Unity客户端人员 与 IOS端研发人员合作的情况

目录

From U3D to iOS

实现原理

1.unity工程目录创建2个文件 NativeCallProxy.m、NativeCallProxy.h 并且放到Unity工程目录Plugins/iOS/unity_ios_plus目录下

2.创建C#调用脚本 定义对应.mm脚本的 调用接口,调用也如下


From U3D to iOS

实现原理

由于U3D无法直接调用Objc或者Swift语言声明的接口,幸好U3D的主要语言是C#,因此可以利用C#的特性来访问C语言所定义的接口,然后再通过C接口再调用ObjC的代码(对于Swift代码则还需要使用OC桥接)。

下面演示:利用C#的特性来访问C语言所定义的接口,然后再通过C接口再调用ObjC的代码

1.unity工程目录创建2个文件 NativeCallProxy.m、NativeCallProxy.h 并且放到Unity工程目录Plugins/iOS/unity_ios_plus目录下

 NativeCallProxy.m代码内容:

#import <Foundation/Foundation.h>
#import "NativeCallProxy.h"//固定写法
@implementation FrameworkLibAPIid<NativeCallsProtocol> api = NULL;
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi
{api = aApi;
}
//固定写法结束
@end//固定写法
extern "C" {
//void showHostMainWindow(const char* color) { return [api showHostMainWindow:[NSString stringWithUTF8String:color]]; };//返回字符串的1个函数
const char*  unityCallGetInitData(){NSString* str=[api unityCallGetInitData];char* ret = nullptr;
//    ret = (char*)malloc([str length]+1);
//    memcpy(ret, [str UTF8String], ([str length])+1);ret = (char*)malloc([str length]);memcpy(ret, [str UTF8String], [str length]);return ret;    
};//无返回的1个函数
void unityCallJumpLogin(){return  [api unityCallJumpLogin];
};//无返回、传入字符串的函数
void unityCallJumpToRecharge(const char* gameStatus,const char* receOBName,const char* methodName){return [api unityCallJumpToRecharge:[NSString stringWithUTF8String:gameStatus] :[NSString stringWithUTF8String:receOBName] :[NSString stringWithUTF8String:methodName]];};void unityCallCloseVC(){return [api unityCallCloseVC];
};//隱私按鈕
void onPrivacyButton(){return [api onPrivacyButton];
}//儲值按鈕
const char* storedValue(){NSString* str=[api storedValue];char* ret = nullptr; ret = (char*)malloc([str length]);memcpy(ret, [str UTF8String], [str length]);return ret;
}//切换游戏
const char* ChangeGame(){NSString* str=[api ChangeGame];char* ret = nullptr;ret = (char*)malloc([str length]);memcpy(ret, [str UTF8String], [str length]);return ret;}}//extern "C" {
//
//}

NativeCallProxy.h代码内容

// [!] important set UnityFramework in Target Membership for this file
// [!]           and set Public header visibility//固定写法
#import <Foundation/Foundation.h>
// NativeCallsProtocol defines protocol with methods you want to be called from managed
@protocol NativeCallsProtocol
@required// other methods 自定义方法
/**获取初始json数据:baseUrl、mac_id、gameType、jwt 【对应mm文件的自定义函数名】*/
-(NSString*)unityCallGetInitData;
/**重新登录	【对应mm文件的自定义函数名的接口】*/
-(void)unityCallJumpLogin;
/**跳充值页前保存数据,充值页返回后把保存的数据发信息给unity 【对应mm文件的自定义函数名的接口】*/
-(void)unityCallJumpToRecharge:(NSString*) gameStatus :(NSString*) receOBName :(NSString*) methodName;//ios——关闭vc 【对应mm文件的自定义函数名的接口】
-(void)unityCallCloseVC;//隱私按鈕 【对应mm文件的自定义函数名的接口】
-(void)onPrivacyButton;//储值按钮 【对应mm文件的自定义函数名的接口】
-(NSString*)storedValue;//ch Game 【对应mm文件的自定义函数名的接口】
-(NSString*)ChangeGame;//自定义方法结束
@end//以下为固定写法
__attribute__ ((visibility("default")))
@interface FrameworkLibAPI : NSObject
// call it any time after UnityFrameworkLoad to set object implementing NativeCallsProtocol methods
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi;@end

勾选iOS平台

2.创建C#调用脚本 定义对应.mm脚本的 调用接口,调用也如下

using System;
using System.Collections;
using System.Collections.Generic;
using LitJson;
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;
using UnityEngine.SceneManagement; //引入  这个命名空间,让unity可以使用 Assets/Plugins/iOS 或 Android/ 这里的dll文件/// <summary>
/// 呼叫安卓或 IOS 工具类
/// </summary>
public class CallAndroidOrIos :MonoBehaviour
{public static CallAndroidOrIos instance;private void Awake(){instance = this;}#region  关于IOS的操作/// <summary>/// 模拟 安卓或iOS ,DLL的类;/// </summary>public class NativeAPI{#if UNITY_EDITOR || UNITY_ANDROID/// <summary>/// 获取 IOS返回的 json数据 :baseUrl、mac_id、gameType、jwt/// </summary> public static string unityCallGetInitData(){return "";}/// <summary>/// 让IOS 呼叫重新登录/// </summary>/// <returns></returns>public static void unityCallJumpLogin(){Debug.Log("呼叫 ios重新登录");}/// <summary>/// IOS充值的返回 /// </summary> public static void unityCallJumpToRecharge(string gameStatus, stringreceOBName, string methodName){}/// <summary>/// 关闭当前 IOS活动页/// </summary>public static  void unityCallCloseVC(){}/// <summary>/// 隐私按钮/// </summary>public static void onPrivacyButton(){}/// <summary>/// 储值被点击/// </summary>public static string storedValue(){return "";}/// <summary>/// 切换G/// </summary>/// <returns></returns>public static string ChangeGame(){return "";}#elif UNITY_IOS || UNITY_TVOS //定义对应.mm脚本的 调用接口-----------[DllImport("__Internal")]public static extern string unityCallGetInitData();[DllImport("__Internal")]public static extern void unityCallJumpLogin();[DllImport("__Internal")]public static extern void unityCallJumpToRecharge(string gameStatus, stringreceOBName, string methodName);[DllImport("__Internal")]public static extern void unityCallCloseVC();[DllImport("__Internal")]public static extern void onPrivacyButton();[DllImport("__Internal")]public static extern string storedValue();[DllImport("__Internal")]public static extern string ChangeGame();
#endif}#endregion/// <summary>/// 被安卓调用过来的 统一函数名称  Public void Give_AnCall(string value)/// </summary>public const string Give_AnCall = "Give_AnCall";/// <summary>/// 当处于同一个物体的时候;用来区分函数名称/// </summary>public const string Give_AnCall2 = "Give_AnCall2";/// <summary>/// 关闭app当前页面/// </summary>public void unityCallCloseActivity(){if (Application.platform ==RuntimePlatform.IPhonePlayer|| Application.platform==RuntimePlatform.OSXEditor){Debug.Log("IOS 关闭当前Activity----------");NativeAPI.unityCallCloseVC();//关闭Ios 活动页}else{Debug.Log("关闭当前Activity----------");AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallCloseActivity");//关闭页面 }}/// <summary>/// 获取 玩家进入哪个游戏类型 [ 0是推币机 1是连连看 -1是未知类型]/// 并且获取到 baseURL mac_id jwt gameType/// </summary> public IEnumerator unityCallGetInitData(Action<JsonData,string> callBack){int Time = 0;string strData="";string Tips="";try{if (Application.platform ==RuntimePlatform.IPhonePlayer){strData = NativeAPI.unityCallGetInitData();}else{AndroidJavaClass activityClass;AndroidJavaObject s_ActivityContext;activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); //只能调用静态s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity"); //可以调用非静态strData = s_ActivityContext.Call<string>("unityCallGetInitData");}}catch (Exception e){Tips = "Error:" + e;if (callBack != null){callBack(null, Tips);}//跳出协程的执行yield break;}while (string.IsNullOrEmpty(strData))//等待回调{yield return new WaitForSeconds(1);Time++;if (Time >= 10){break; //跳出循环}}//还是没有 收到安卓返回数据  if (string.IsNullOrEmpty(strData)){if (callBack!=null){Tips = "Get the Android Or IOS data timeout";//获取安卓数据超时callBack(null, Tips);} }else{JsonData jsonData = JsonMapper.ToObject(strData);if (callBack!=null){callBack(jsonData, "successful"); }}}/// <summary>/// 跳转到 充值界面 (1.当前游戏场景名称 ,2.物体名称 ,3.安卓返回参数到 哪个函数接收) /// </summary> public void unityCallJumpToRecharge(string ScreenName, string receOBName, string methodName){if (Application.platform ==RuntimePlatform.IPhonePlayer){NativeAPI.unityCallJumpToRecharge(ScreenName,receOBName,methodName);//跳转到 充值}else{Debug.Log("呼叫 安卓跳转充值!----------------");AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallJumpToRecharge",ScreenName,receOBName,methodName); }}/// <summary>/// 跳转到 重新登录界面/// </summary>public void unityCallJumpLogin(){if (Application.platform ==RuntimePlatform.IPhonePlayer){NativeAPI.unityCallJumpLogin();//IOS 进入 重新登录页面}else{Debug.Log("跳转到重新登录的Activity--------------");AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallJumpLogin");activityClass = null;s_ActivityContext = null;}}/// <summary>/// 显示UnityLog到 安卓调试窗/// </summary>public void unityCallPrintLog(string log){if (Application.platform ==RuntimePlatform.IPhonePlayer){//TODO }else{AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallPrintLog",log);}}/// <summary> 打开隐私按钮 </summary>public void onPrivacyButton(){if (Application.platform ==RuntimePlatform.IPhonePlayer){NativeAPI.onPrivacyButton();}else{Debug.Log("打开隐私按钮");}}/// <summary> 打开储值 </summary>public void storedValue(){if (Application.platform == RuntimePlatform.IPhonePlayer){Debug.Log("ios打开储值:"+NativeAPI.storedValue()); }else{Debug.Log("打开储值按钮");if (Application.platform == RuntimePlatform.WindowsEditor){//LogoGM.instance.HeroInfo_PlayCount(5);//默认给+5个//LogoGM.instance.HeroInfoSave();//PC端 增加可玩次数保存}}}/// <summary> 查询是否切换游戏 </summary>/// <returns></returns>public string ChangeGame(){if (Application.platform == RuntimePlatform.IPhonePlayer){return "IOS查询是否切换" + NativeAPI.ChangeGame();}else{return "PC查询游戏切换";}}/// <summary>/// IOS调用Unity的方法:UnitySendMessage("物体名", "函数名", "回调字符串");/// </summary>/// <param name="msg"></param>public void ReceIosMsg(string msg){Debug.Log("IOS 回调的信息");/*//根据游戏的场景划分 确定回调逻辑int scenceId = SceneManager.GetActiveScene().buildIndex;if (string.IsNullOrEmpty(msg)){Debug.Log(scenceId+"场景 收到IOS消息为空字符");}else{string strType;string strCode;//字符串转json对象JsonData jsonData = JsonMapper.ToObject(msg);switch (scenceId){case 0://场景0try{strType = jsonData["type"].ToString();strCode = jsonData["str"].ToString();if (strType=="ChuShiHua"){int code = int.Parse(strCode);if (code==0)//非游戏 静止在这个界面{Debug.Log(scenceId+"场景收到非游戏Code,等待跳转");//SetOrientationPortrait();//设置为竖屏mSpr.gameObject.SetActive(false);TestUpsideDown(1);}else{Debug.Log("正常游戏");toMenu();}}else{Debug.Log(scenceId+"场景 收到的不是初始化字段:"+strType);}}catch (Exception e){Debug.LogError(string.Format("{0} 场景 解析数据出错 原数据:{1}",scenceId,msg));}break;case 1://场景1try{strType = jsonData["type"].ToString();strCode = jsonData["str"].ToString();if (strType == "APPStore_Scuess"){//TODO 储值成功 添加可玩次数Debug.Log("储值成功");HeroInfo_PlayCount(9999);HeroInfoSave();//场景1的储值}else{Debug.Log(scenceId+"场景 收到的不是储值字段:"+strType);}}catch (Exception e){Debug.LogError(string.Format("{0} 场景 解析数据出错 原数据:{1}",scenceId,msg));}break;}}*/}
}

相关文章:

Unity3D与iOS的交互 简单版开箱即用

本文适合的情况如下&#xff1a; Unity客户端人员 与 IOS端研发人员合作的情况 目录 From U3D to iOS 实现原理 1.unity工程目录创建2个文件 NativeCallProxy.m、NativeCallProxy.h 并且放到Unity工程目录Plugins/iOS/unity_ios_plus目录下 2.创建C#调用脚本 定义对应.mm脚…...

限制LitstBox控件显示指定行数的最新数据(3/3)

实例需求&#xff1a;由于数据行数累加增加&#xff0c;控件加载的数据越来越多&#xff0c;每次用户都需要使用右侧滚动条拖动才能查看最新数据。 因此希望ListBox只加载最后10行数据&#xff08;不含标题行&#xff09;&#xff0c;这样用户可以非常方便地选择数据&#xff…...

Maven进阶系列-仓库和镜像

Maven进阶系列-仓库和镜像 文章目录 Maven进阶系列-仓库和镜像1. 仓库1.1 仓库类型1.2 寻找jar的基本优先级顺序&#xff1a;1.3 仓库优先次序验证示例 2. settings.xml文件2.1 mirrors2.1.1 没有配置mirror2.1.2 配置了mirror2.1.3 <mirrorOf> 2.2 servers2.3 profiles …...

mac下载安装jenkins

下载 https://get.jenkins.io/war/ 启动 使用命令行启动 java -jar jenkins.war 浏览器访问 IP:8080 或 localhost:8080 &#xff0c;对jenkins进行配置&#xff0c;刚开始需要输入密码 终端会展示密码和密码存放位置 jenkins插件下载地址&#xff0c; 下载后自行上传。 I…...

Mac上的iTerm2和Oh My Zsh 的安装(安装过程和失败详解)

前言&#xff08;无重点&#xff0c;安装往后看&#xff09; 由于在很多人的安利下&#xff0c;说很好用&#xff0c;作者今天花费了4个小时用血的教训总结出来的安装教程&#xff0c;我在安装过程中遇到的最大的问题就是 1. curl: (7) Failed to connect to raw.githubusercon…...

阿里云OS系统Alibaba Cloud Linux 3系统的安全更新命令

给客户部署的服务&#xff0c;进入运维阶段&#xff0c;但是经常被客户监测到服务器漏洞&#xff0c;现在整理一下&#xff0c;服务器漏洞问题更新命令步骤。 服务器系统&#xff1a; 阿里云linux服务器&#xff1a;Alibaba Cloud Linux 3 漏洞类型和描述&#xff1a; #3214…...

你写的Python代码到底多快?这些测试工具了解了解

当我们写完一个脚本或一个函数&#xff0c;首先能保证得到正确结果&#xff0c;其次尽可能的快&#xff08;虽然会说Py慢&#xff0c;但有的项目就是得要基于Py开发&#xff09; 本期将总结几种获取程序运行时间的方法&#xff0c;极大的帮助对比不同算法/写法效率 插播&…...

网际控制报文协议ICMP

网际控制报文协议ICMP ​ 为了更有效的转发IP数据报和提高交付成功的机会&#xff0c;在网际层使用ICMP&#xff08;Internet Control Message Protocol&#xff09;协议&#xff0c;其允许主机或路由器报告差错情况和提供有关异常情况的报告。ICMP报文装在IP数据报中&#xf…...

海外腾讯云服务器配置域名的详细说明!!

本文首要针对腾讯云服务器装备域名的问题进行具体的说明&#xff0c;包含域名的品种、注册方法、解析进程以及安全性等方面的介绍&#xff0c;帮助用户更好的理解腾讯云服务器装备域名的全进程。 一、域名的品种 1.域名是互联网上仅有标识一台计算机或一个网络资源的名称&#…...

听GPT 讲Rust源代码--library/std(12)

题图来自 Decoding Rust: Everything You Need to Know About the Programming Language[1] File: rust/library/std/src/os/watchos/mod.rs 该文件&#xff08;rust/library/std/src/os/watchos/mod.rs&#xff09;的作用是为Rust标准库提供支持WatchOS操作系统的特定功能。 W…...

06、Caused by: java.nio.charset.MalformedInputException: Input length = 1

目录 问题&#xff1a;原因&#xff1a;解决方法&#xff1a; 问题&#xff1a; Caused by: java.nio.charset.MalformedInputException: Input length 1 原因&#xff1a; 应该是中文有哪些文字导致的。 yml 编码格式出错 解决方法&#xff1a; 直接这里把GBK改成 utf-8…...

探索 Java 8 中的 Stream 流:构建流的多种方式

人嘛&#xff0c;要懂得避嫌… 开篇引入 Java 8引入了Stream流作为一项新的特性&#xff0c;它是用来处理集合数据的一种函数式编程方式。Stream流提供了一种更简洁、高效和易于理解的方法来操作集合数据&#xff0c;同时也能够实现并行处理&#xff0c;以提高性能。 以下是St…...

安卓Apk布局修改从入门到精通

安卓Apk布局修改从入门到精通 课程大纲 本次教程的目标是&#xff0c;学会将安卓apk反向工程后&#xff0c;如何找到需要修改的布局、对布局修改、对布局进行美化&#xff0c;如何隐藏布局&#xff08;按钮等&#xff09;&#xff0c;以及如何在界面上添加按钮并响应点击事件&…...

React Native 样式及其布局

React Native 样式及其布局 参考 https://reactnative.cn/docs/flexbox 一、样式 在 React Native 中&#xff0c;你并不需要学习什么特殊的语法来定义样式。我们仍然是使用 JavaScript 来写样式。所有的核心组件都接受名为style的属性。这些样式名基本上是遵循了 web 上的 …...

基于51单片机的智能指纹考勤系统设计

**单片机设计介绍&#xff0c;1661【毕设课设】基于51单片机的智能指纹考勤系统设计-原理图-PCB-程序-报告 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机的智能指纹考勤系统是一种利用51单片机作为主控芯片&#x…...

I/O性能优化——这一篇就足够啦

背景 继上一篇CPU性能优化文章 &#xff0c;本次向大家分享关于I/O性能优化的分析套路以及常见措施。后续还有关于内存及网络优化的篇章。 基本概念 对于I/O我们先了解几个概念&#xff0c;文件系统&#xff0c;磁盘&#xff0c;文件。 磁盘 磁盘为系统提供了最基本的持久化存…...

【蓝桥杯选拔赛真题44】python小蓝晨跑 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python小蓝晨跑 一、题目要求 1、编程实现 2、输入输出 二、算法分析...

摩托车商家做展示预约小程序的作用

摩托车与电动车是人们短距离出行的主要工具&#xff0c;而其使用寿命一般是3年左右及以上、一家可能有多个&#xff0c;市场人群庞大且复购属性强&#xff0c;所以其经营商家也非常多。 如今互联网深入&#xff0c;在品牌宣传、客户获取、信息承载、营销等方面需要车辆经营商家…...

数据库实验:SQL的多表数据查询

目录 实验目的实验内容实验要求实验过程实验代码结果示意 书接上文&#xff0c;但是感觉之前的形式不太好用&#xff0c;至少不是很方便观看&#xff0c;所以这篇尝试改变一下写法&#xff0c;希望可以提升一些观感 实验目的 (1) 掌握RDBMS的数据多表查询功能 (2) 掌握SQL语言…...

【使用Python编写游戏辅助工具】第一篇:概述

引言 欢迎阅读本系列文章&#xff0c;本系列将带领读者朋友们使用Python来实现一个简单而有趣的游戏辅助工具。 写这个系列的缘由源自笔者玩了一款游戏。正巧&#xff0c;笔者对Python编程算是有一定的熟悉&#xff0c;且Python语言具备实现各种有趣功能的能力&#xff0c;因…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...