Unity3d UGUI如何优雅的实现Web框架(Vue/Rect)类似数据绑定功能(含源码)
前言
Unity3d的UGUI系统与Web前端开发中常见的数据绑定和属性绑定机制有所不同。UGUI是一个相对简单和基础的UI系统,并不内置像Web前端(例如 Vue.js或React中)那样的双向数据绑定或自动更新UI的机制。UGUI是一种比较传统的 UI 系统,它更侧重于基于事件的UI更新和手动控制视图的更新。在 UGUI中,如果数据变化了,开发者需要手动更新UI元素(例如文本、按钮状态、进度条等)。这种方式虽然灵活,但需要开发者自己处理每个UI更新的时机和逻辑。
对比数据可以通过双大括号 {{}} 语法直接绑定到模板中,无需手动处理DOM元素;而Unity3d的Text修改文字内容则需要通过Text.text属性来修改,对比起来比较麻烦,特比实在数据变量频繁变更的情况下。要是在Unity的UGUI中实现了数据绑定,可以提高代码冗余、提高UI数据更新开发效率、解耦数据和UI的关联。目前实现的功能有Text内{{}}绑定数据、颜色绑定(Graphic.color)、图片绑定(Image.sprite)、列表绑定和属性绑定等功能。
尽管它有着诸多的优势,如减少了代码冗余、提高了开发效率和提高了应用的可维护性。它通过解耦视图和数据,使得开发者能够更关注业务逻辑,而不是繁琐的 UI 更新操作。这使得开发者能够更加专注于应用的核心功能,提升了代码质量和可扩展性。但是数据绑定也有一些挑战,特别是性能优化方面(尤其是在大规模数据或复杂 UI 交互时)。
关注并私信 U3D数据绑定 免费获取源码(底部公众号)。
效果
文字绑定和列表刷新:
滑动条绑定:
列表绑定:
颜色绑定:
实现
大致实现思路如下:
1.先建立一个类(DataContext)作为管理键值对的容器,它允许通过键(key)来访问和修改与之相关联的值(value)。这个类还支持在值发生更改时触发一个事件(Changed),事件触发时,会传递触发变化的键。
using System;
using System.Collections.Generic;public class DataContext
{public event Action<string> contextChanged = delegate { };private IDictionary<string, object> m_ActiveBinds = new Dictionary<string, object>();public bool ContainsKey(string key){return m_ActiveBinds.ContainsKey(key);}
}
2.再建立一个DataBindContext类,管理和更新数据绑定的类。它通过 DataContext 来存储数据,并在数据变化时通知相关的 UI 组件更新。:当数据变化时,BindChanged 方法会被触发,自动更新所有依赖于该数据的 UI 组件。
using UnityEngine;//数据绑定类
public class DataBindContext : MonoBehaviour
{private DataContext m_DataContext;public object this[string key]{get { return m_DataContext[key]; }set{if (m_DataContext == null){m_DataContext = new DataContext();m_DataContext.contextChanged += BindChanged;}m_DataContext[key] = value;}}public void BindChanged(string key){var children = GetComponentsInChildren<IBindable>();if (children == null)return;for (var i = 0; i < children.Length; i++)if (string.IsNullOrEmpty(children[i].key) || children[i].key == key)children[i].Bind(m_DataContext);}}
3.再建立IBindable 接口,IBindable 提供了一个统一的接口来进行绑定键的数据更新,包括key属性(用于绑定的key值)和Bind(DataContext context)方法,Bind方法接收一个 DataContext 参数,UI 组件通过此方法将数据模型绑定到自身,监听数据变化,并在数据变化时自动更新UI。
public interface IBindable
{string key { get; }void Bind(DataContext context);
}
Text绑定
Text内采用“{{}}”绑定数据,是最最常用的数据绑定,例如{{Number:N0}}{{Test}}绑定了Number和Test的键值,当检测到数据变更会进行刷新。
显示前:
代码调用变更
DataBindContext.instance?.SetKeyValue("Number", 57729);
DataBindContext.instance?.SetKeyValue("Test", "测试绑定");
显示后:
Text的绑定实现就是通过实现IBindable接口的Bind方法,在其中将匹配的字符串进行替换变量数值,代码如下:
m_Text.text = Regex.Replace(m_OriginalText, @"\{\{[^}]*}}", m =>
{var target = m.Value.Substring(2, m.Value.Length - 4).Split(':');var key = target[0];if (context.ContainsKey(key)) {var val = context[key];if (target.Length == 2 && val is IFormattable) {var format = target[1];return ((IFormattable) val).ToString(format, CultureInfo.CurrentCulture);}return val.ToString();
}return "";
});
属性绑定
属性绑定是将两个UGUI的组件属性直接做一个关联,当然关联之前开发者也需要了解两个属性间值是否真的能关联匹配。这里以Slider的value 关联到 Text的text属性为例:
这样运行时候Slider的value属性就会同步到Text.text显示:
同时属性绑定可以选择方向和多种更新同步方式:
不同更新同步模式的代码:
private void Update()
{if (m_Update == UpdateMethod.OnUpdate) {UpdateBind();}
}private void FixedUpdate()
{if (m_Update == UpdateMethod.OnFixedUpdate) {UpdateBind();}
}private void LateUpdate()
{if (m_Update == UpdateMethod.OnLateUpdate) {UpdateBind();}
}
属性更新实现:
public void UpdateBind()
{if (m_SourceProperty == null || m_DestinationProperty == null){return;}if (m_CachedSourceProperty == null || m_CachedSourceProperty.Name != m_SourceProperty|| m_CachedDestinationProperty == null || m_CachedDestinationProperty.Name != m_DestinationProperty){Cache();}switch (m_Direction){case Direction.SourceUpdatesDestination:if (m_CachedDestinationProperty.PropertyType == typeof(string)){m_CachedDestinationProperty.SetValue(m_Destination, m_CachedSourceProperty.GetValue(m_Source, null).ToString(),null);}else{m_CachedDestinationProperty.SetValue(m_Destination, m_CachedSourceProperty.GetValue(m_Source, null), null);}break;case Direction.DestinationUpdatesSource:if (m_CachedSourceProperty.PropertyType == typeof(string)){m_CachedSourceProperty.SetValue(m_Source, m_CachedDestinationProperty.GetValue(m_Destination, null).ToString(),null);}else{m_CachedSourceProperty.SetValue(m_Source, m_CachedDestinationProperty.GetValue(m_Destination, null), null);}break;}
}public void Cache()
{m_CachedSourceProperty = m_Source.GetType().GetProperty(m_SourceProperty);m_CachedDestinationProperty = m_Destination.GetType().GetProperty(m_DestinationProperty);
}
图片绑定
[SerializeField]
[Header("绑定对象")]
private Image m_Image;
[SerializeField]
[Header("绑定键名")]
private string m_Key;public string key
{get { return m_Key; }
}public void Bind(DataContext context)
{if (context.ContainsKey(m_Key)){m_Image.sprite = (Sprite)context[m_Key];}
}
颜色绑定
[SerializeField]
[Header("绑定对象")]
private Graphic m_Graphic;
[SerializeField]
[Header("绑定键名")]
private string m_Key;public string key
{get { return m_Key; }
}public void Bind(DataContext context)
{if (context.ContainsKey(m_Key)){m_Graphic.color = (Color)context[m_Key];}
}
滑动条绑定
private Slider m_Slider;[Header("绑定键名")]
public string m_Key;public string key
{get { return m_Key; }
}
public void Bind(DataContext context)
{if (m_Slider == null)m_Slider = GetComponent<Slider>();if (context.ContainsKey(key)){m_Slider.value = (float)context[key];}
}
列表绑定
列表的绑定其实需要预设节点名称和绑定键名等设置,如下:
[SerializeField]
[Header("列表节点预设")]
private GameObject m_ItemPrefab;
[SerializeField]
[Header("节点键名")]
public string m_ItemKey;
[SerializeField]
[Header("绑定键名")]
public string m_Key;
数据绑定刷新的代码如下:
if (m_ItemPrefab == null)
{Debug.LogWarning("节点预设为空,无法绑定列表!");return;
}m_Context = new DataContext();if (context.ContainsKey(m_Key))
{var list = (ObservableList)context[m_Key];if (list.Count > itemObjList.Count){for (int i = itemObjList.Count; i < list.Count; i++){GameObject go = GameObject.Instantiate(m_ItemPrefab);go.transform.SetParent(transform, false);go.transform.localScale = Vector3.one;go.transform.localEulerAngles = Vector3.zero;go.transform.name = i.ToString("D4") + "item";itemObjList.Add(go);}}elsefor (int i = list.Count; i < itemObjList.Count; i++)itemObjList[i].SetActive(false);for (int i = 0; i < list.Count; i++){var itemData = list[i];var item = itemObjList[i];var bindables = item.GetComponentsInChildren<IBindable>(true);var properties = itemData.GetType().GetProperties();var model = item.GetComponent<IModel>();if (model != null)model.model = itemData;for (var j = 0; j < properties.Length; j++){var p = properties[j];m_Context[m_ItemKey + "." + p.Name] = p.GetValue(itemData, null);}for (var j = 0; j < bindables.Length; j++)bindables[j].Bind(m_Context);itemObjList[i].SetActive(true);}}
其核心思路就是存在该键变更时,根据列表数据显示或者隐藏、并刷新所有子节点。通过键的值以列表的形式,节点不够时克隆节点的预设,生成节点,将单个节点的数据根据绑定配置刷新到对应的组件上,直到所有节点刷新完毕。
同时预设的节点数据需要与定义的类型结构统一,这里以排行榜为例,其数据结构如下:
class RankItem
{public int index { get; set; }public string name { get; set; }public float score { get; set; }
}
index、name和score分别表示排名、玩家名称和分数。
所以单个节点的预设的绑定应该如下配置:
列表的键采用Ranks,同时通过如下代码生成假数据:
int count = 10;
for (int i = count; i > 0; i--)
{m_RankItems.Add(new RankItem{index = count - i + 1,score = i * 100 + Random.Range(0, 7.6f),name = "玩家名称" + (count - i + 1)});
}DataBindContext.instance?.SetKeyValue("Ranks", m_RankItems);
绑定列表的配置最终如下图:
绑定与变更
绑定值变更数据的键值变更采用如下代码:
DataBindContext m_Context["键名"] = 值;
单例模式也可采用来修改值:
DataBindContext.instance?.SetKeyValue("键名", 值);
演示功能
这里简单搭建一个覆盖功能的UI:
挂上对应的脚本(注意DataBindContext 需要挂在最外层)后运行效果:
项目源码
https://download.csdn.net/download/qq_33789001/90195629
相关文章:
Unity3d UGUI如何优雅的实现Web框架(Vue/Rect)类似数据绑定功能(含源码)
前言 Unity3d的UGUI系统与Web前端开发中常见的数据绑定和属性绑定机制有所不同。UGUI是一个相对简单和基础的UI系统,并不内置像Web前端(例如 Vue.js或React中)那样的双向数据绑定或自动更新UI的机制。UGUI是一种比较传统的 UI 系统ÿ…...
【JavaEE进阶】@RequestMapping注解
目录 📕前言 🌴项目准备 🌲建立连接 🚩RequestMapping注解 🚩RequestMapping 注解介绍 🎄RequestMapping是GET还是POST请求? 🚩通过Fiddler查看 🚩Postman查看 …...
Vue.js组件开发-自定义文件上传
在Vue.js中开发自定义文件上传组件,创建一个独立的Vue组件来处理文件选择和上传的逻辑。这个组件可以包含文件选择器、上传进度条、上传状态提示等元素,并根据需要进行自定义。 示例: <template><div class"file-upload"…...
CES Asia 2025的低空经济展区有哪些亮点?
CES Asia 2025(赛逸展)的低空经济展区有以下亮点: • 前沿科技产品展示: 多款新型无人机将亮相,如固定翼无人机和系留无人机的最新型号,其在监测、救援和货物运输等方面功能强大。此外,还有可能…...
公路边坡安全监测中智能化+定制化+全面守护的应用方案
面对公路边坡的安全挑战,我们如何精准施策,有效应对风险?特别是在强降雨等极端天气下,如何防范滑坡、崩塌、路面塌陷等灾害,确保行车安全?国信华源公路边坡安全监测解决方案,以智能化、定制化为…...
Arduino 驱动GY-271(HMC5883L)三轴磁场模块
Arduino 驱动GY-271(HMC5883L)三轴磁场模块 简介特征参数原理图寄存器通信测量步骤接线主要代码结果 简介 HMC5883L 是一种表面贴装的高集成模块,并带有数字接口的弱磁传感器芯片,应用于低成本罗盘和磁场的检测领域。HMC5883L 包…...
ImportError: cannot import name ‘einsum‘ from ‘einops‘
报错: from einops import einsum ImportError: cannot import name einsum from einops 测试代码: python -c "from einops import einsum" 解决方法: pip uninstall einops pip install einops Successfully installed ein…...
GitLab安装及使用
目录 一、安装 1.创建一个目录用来放rpm包 2.检查防火墙状态 3.安装下载好的rpm包 4.修改配置文件 5.重新加载配置 6.查看版本 7.查看服务器状态 8.重启服务器 9.输网址 二、GitLab的使用 1.创建空白项目 2.配置ssh 首先生成公钥: 查看公钥 把上面的…...
攻防世界web第二题unseping
这是题目 <?php highlight_file(__FILE__);class ease{private $method;private $args;function __construct($method, $args) {$this->method $method;$this->args $args;}function __destruct(){if (in_array($this->method, array("ping"))) {cal…...
Bitmap(BMP)图像信息验证
Bitmap BMP图像信息验证 参考文章例程目的一、Bitmap图像结构二、获取文件大小三、获取应用程序路径四、获取目录中所有内容(包括子目录)五、Bitmap图像信息验证六、主函数测试七、测试结果 参考文章 在Windows下C语言获取当前应用程序运行路径并获取指定目录下所有文件Bitmap…...
Faster R-CNN
文章目录 摘要Abstract1. 引言2. 框架2.1 RPN2.1.1 网络结构2.1.2 损失函数2.1.3 训练细节 2.2 训练过程 3. 创新点和不足3.1 创新点3.2 不足 参考总结 摘要 Faster R-CNN是针对Fast R-CNN缺点改进的目标检测模型。为了解决候选区域生成耗时长的问题,Faster R-CNN提…...
MySQL数据库锁
MySQL中读写不互斥(前提是没有使用串行化隔离级别),但是写写操作要互斥才行,MySQL中使用锁机制来实现写写互斥。 按照锁的粒度可以分为:全局锁、表锁、行锁以及其他位于二者之间的间隙锁。 全局锁 锁定整个数据库&…...
树莓派A+安装lnmp-第一步,安装mariadb
20:26 2024/12/27 第一件事情,当然是超频!!! raspi-config 4 Performance Options,选择P1 Overclock,可配置超频 不要贪心,选择900就可以!!! rootpia4:~#…...
C++:单例模式
创建自己的对象,同时确保对象的唯一性。 单例类只能有一个实例☞静态成员static☞静态成员 必须类外初始化 单例类必须自己创建自己的唯一实例 单例类必须给所有其他对象提供这一实例 静态成员类内部可以访问 构造函数私有化☞构造函数私有外部不能创建&#x…...
【数据结构】数据结构整体大纲
数据结构用来干什么的?很简单,存数据用的。 (这篇文章仅介绍数据结构的大纲,详细讲解放在后面的每一个章节中,逐个击破) 那为什么不直接使用数组、集合来存储呢 ——> 如果有成千上亿条数据呢ÿ…...
网页数据的解析提取之Beautiful Soup
前面博客介绍了正则表达式的相关用法,只是一旦正则表达式写得有问题,得到的结果就可能不是我们想要的了。而且每一个网页都有一定的特殊结构和层级关系,很多节点都用id或 class 作区分所以借助它们的结构和属性来提取不也可以吗? 本篇博客我…...
Ai写作人工智能官网模板源码
Mortal是响应式的Tailwind CSS 模板,适用于AI写作和文案智能生成网站。 可用于撰写博客内容、数字广告文案、技术写作、SEO内容、登陆页面文案、社交媒体内容、电子邮件营销、网站文案等。使用世界上流行的响应式CSS框架Tailwind CSS、HTML5、CSS3 和 Javascript构…...
VSCode 插件开发实战(七):插件支持了哪些事件,以及如何利用和监听这些事件
前言 VSCode 作为现代开发者的首选编辑器之一,其核心优势在于其高度可扩展性。通过自定义插件,开发者可以根据自己的需求对编辑器进行功能扩展和优化。在这些插件开发过程中,事件处理和监听机制尤为重要,它们允许插件在特定事件发…...
现货量化合约跟单系统开发策略指南
随着加密货币市场的日益发展,量化交易和合约跟单已经成为了投资者在市场中获取稳定收益的重要手段。现货量化合约跟单系统作为一种自动化交易工具,可以帮助用户自动执行交易策略,同时也能跟随成功的交易者进行复制交易,从而降低投…...
Flink的Watermark水位线详解
一、Flink的时间语义 Flink有如下三种时间语义: Flink的三种时间语义-CSDN博客 在实际应用中,一般会采用事件时间语义。而正如前面所说的,事件时间语义需要等窗口的数据全部到齐了,才能进行窗口计算。那么,什么时候数…...
香港 GPU 服务器托管引领 AI 创新,助力 AI 发展
在当今科技飞速发展的时代,中国人工智能市场呈现出蓬勃发展的态势,对高性能计算资源的需求日益增长,而香港 GPU 服务器托管服务凭借其卓越的优势,成为众多企业的首选,同时其三地灾备方案更是为企业数据安全和业务连续性…...
FFmpeg来从HTTP拉取流并实时推流到RTMP服务器
当使用FFmpeg来从HTTP拉取流并实时推流到RTMP服务器时,你可以使用以下命令: ffmpeg -i http://输入流地址 -c:v copy -c:a copy -f flv rtmp://RTMP服务器地址/应用名称/流名称 这是一个基本的命令示例,其中: - -i http://输入流地…...
vue 集成 webrtc-streamer 播放视频流 - 解决阿里云内外网访问视频流问题
资料: 史上最详细的webrtc-streamer访问摄像机视频流教程-CSDN博客 webrtc目录 前端集成 html文件夹里的webrtcstreamer.js,集成到前端,可以访问webrtc,转换rtsp为webrtc视频流,在前端video中播放 <videoref&quo…...
Spring创建异步线程池方式
在Java 11中,可以通过多种方式创建异步线程池,包括使用原生的ExecutorService和Spring的异步支持(如Async注解结合线程池)。以下是具体实现方式。 方式 1:使用原生ExecutorService Java 11 的ExecutorService提供灵活…...
《PHP MySQL 插入数据》
《PHP MySQL 插入数据》 介绍 PHP是一种广泛使用的服务器端脚本语言,而MySQL是一种流行的关系型数据库管理系统。在Web开发中,经常需要将用户输入的数据存储到数据库中。本文将详细介绍如何使用PHP和MySQL实现数据的插入操作。 环境准备 在开始之前&…...
2022博客之星年度总评选开始了
作者简介:陶然同学 专注于Java领域开发 熟练掌握Java、js等语言的“Hello World” CSDN原力计划作者、CSDN内容合伙人、Java领域优质作者、Java领域新星作者、51CTO专家、华为云专家、阿里云专家等 🎬 陶然同学🎥 由 陶然同学 原创&#…...
0055. shell命令--useradd
目录 55. shell命令--useradd 功能说明 语法格式 选项说明 选项 退出值 相关文件 /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/skel/ /etc/login.defs /etc/default/useradd 实践操作 注意事项 55. shell命令--useradd 功能说明 useradd 命令是 Lin…...
HTML5适配手机
要使 HTML5 网站适配手机设备,您可以遵循以下几个步骤和最佳实践: 1. 使用视口(Viewport) 在 HTML 文档的 <head> 部分添加视口元标签,以确保页面在移动设备上正确缩放和显示: <meta name"…...
网络安全 | 5G网络安全:未来无线通信的风险与对策
网络安全 | 5G网络安全:未来无线通信的风险与对策 一、前言二、5G 网络的技术特点2.1 超高速率与低延迟2.2 大容量连接与网络切片 三、5G 网络面临的安全风险3.1 网络架构安全风险3.2 设备终端安全风险3.3 应用场景安全风险3.4 用户隐私安全风险 四、5G 网络安全对策…...
Markov test笔记
补充知识 来源于数学之美第五章: 到了 19 世纪,概率论的发展从相对静止的随机变量的研究发展到随机变量的时间序列 ( s 1 , s 2 , s 3 , … ) (s_1, s_2, s_3, \dots) (s1,s2,s3,…),即随机过程(动态的)。这在…...
docker 搭建集群
准备3台机器: #dockermaster 192.168.31.150 sudo hostnamectl set-hostname dockermaster #初始化主节点 docker swarm init --advertise-addr 192.168.31.150 #查看集群是否搭建成功 docker node ls #dockernode1 192.168.31.151 sudo hostnamectl set-hostname …...
C# WPF读写STM32/GD32单片机Flash数据
1.安装jlink 下载你需要的Jlink版本 JLink-Windows-V792k-x86-64 JLink-Windows-V810k-x86-64 https://download.csdn.net/download/hmxm6/90178195 2.Visual Studio创建WPF项目 如果没有这个选项请看 https://blog.csdn.net/hmxm6/article/details/132914337 创建完…...
[图形渲染]【Unity Shader】【游戏开发】 Shader数学基础17-法线变换基础与应用
在计算机图形学中,法线(normal) 是表示表面方向的向量。它在光照、阴影、碰撞检测等领域有着重要作用。本文将介绍如何在模型变换过程中正确变换法线,确保其在光照计算中的正确性,特别是法线与顶点的变换问题。 1. 法线与切线的基本概念 法线(Normal Vector) 法线(或…...
MySQL外键类型与应用场景总结:优缺点一目了然
前言: MySQL的外键简介:在 MySQL 中,外键 (Foreign Key) 用于建立和强制表之间的关联,确保数据的一致性和完整性。外键的作用主要是限制和维护引用完整性 (Referential Integrity)。 主要体现在引用操作发生变化时的处理方式&…...
Axure10
如果还是不行就将字体图标安装在控制面板–字体下 打开原型了之后,icon没有 一定要将字体库放到–》控制面板\外观和个性化\字体 里面...
数据结构(单向循环链表)
循环单向链表 所谓的循环,指得是将链表末尾节点的后继指针指向头结点。比如,单向链表变成循环链表的示意 图如下所示: 循环链表的操作跟普通链表操作基本上是一致的,只要针对循环特性稍作修改即可。 sclist.h #ifndef __SCLIST_…...
springboot项目搭建
springboot搭建 问题描述不够清晰,无法提供具体的代码解决方案。"springboot搭" 这个表述不明确是要进行什么操作,比如搭建项目、搭建环境、搭建服务等。 如果你是想要创建一个基本的Spring Boot项目,可以使用Spring Initializr&…...
五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测
目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 光伏功率预测!五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测(Matlab2023b 多输入单输出) 1.程序已经调试好,替换数据集后,仅运…...
02-18.python入门基础一基础算法
(一)排序算法 简述: 在 Python 中,有多种常用的排序算法,下面为你详细介绍几种常见的排序算法及其原理、实现代码、时间复杂度以及稳定性等特点,并对比它们适用的场景。 冒泡排序(Bubble Sor…...
条款19 对共享资源使用std::shared_ptr
目录 一、std::shared_ptr 二、std::shared_ptr性能问题 三、control block的生成时机 四、std::shared_ptr可能存在的问题 五、使用this指针作为std::shared_ptr构造函数实参 六、std::shared_ptr不支持数组 一、std::shared_ptr<T> shared_ptr的内存模型如下图&…...
TCP-UDP调试工具推荐:Socket通信测试教程(附详细图解)
前言 在网络编程与应用开发中,调试始终是一项不可忽视的重要环节。尤其是在涉及TCP/IP、UDP等底层网络通信协议时,如何确保数据能够准确无误地在不同节点间传输,是许多开发者关注的核心问题。 调试的难点不仅在于定位连接建立、数据流控制及…...
算法练习——模拟题
前言:模拟题的特点在于没有什么固定的技巧,完全考验自己的代码能力,因此有助于提升自己的代码水平。如果说一定有什么技巧的话,那就是有的模拟题能够通过找规律来简化算法。 一:替换所有问号 题目要求: 解…...
Windows下播放文件作为麦克风声源的一种方式
近期测试一种外语的ASR识别成功率,样本素材是懂这门语言的同事录制的mp3文件。测试client端原本是从麦克风拾音生成媒体流的。 这样,就需要想办法把mp3文件转换为测试client的输入声音。物理方式上,可以用一根音频线,把电…...
微信流量主挑战:用户数30!新增文档转化功能,解决docker运行jar包报错SimSun找不到的问题(新纪元5)
哎呀,今天忙到飞起,文章晚点更新啦!不过好消息是,我们的小程序用户终于突破30啦,感谢大家的支持!而且,大家期待已久的文档转化功能明天就要上线啦,目前支持word转pdf,pdf…...
BUU LFI COURSE 1
BUU LFI COURSE 1 启动环境 isset函数检查输入是否为空,使用GET传参file,然后赋值给$str 在调用传参内容 我们是找flag那我们输入?file/flag试试 输入后就得到了flag flag{8c108da2-a579-4ec4-b447-92d9265b8dd4}...
Spark SQL DML语句
【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客 《Spark SQL大数据分析快速上手》【摘要 书评 试读】- 京东图书 Spark本地模式安装_spark3.2.2本地模式安装-CSDN博客 DML(Data Manipulation Language,数据操作语言)操作主要用来对…...
逻辑控制语句
一、逻辑控制语句 条件判断 if循环 for、while 二、条件判断 if 1、语法 if 条件:条件为真的操作条件为真的操作 else:条件为假的操作条件为假的操作 data_01 int(input("数字: "))if data_01 > 10:print("ok!!!")print("正确!!!")prin…...
PlasmidFinder:质粒复制子的鉴定和分型
质粒(Plasmid)是一种细菌染色体外的线性或环状DNA分子,也是一种重要的遗传元素,它们具有自主复制能力,可以在细菌之间传播,并携带多种重要的基因(如耐药基因与毒力基因等)功能。根据质粒传播的特性…...
OSCP打靶大冒险之Solidstate:多端口获取信息,shell逃逸,计划任务提权
声明! 学习资源来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…...
【Java-tesseract】OCR图片文本识别
文章目录 一、需求二、概述三、部署安装四、技术细节五、总结 一、需求 场景需求:是对识别常见的PNG,JPEG,TIFF,GIF图片识别,环境为离线内网。组件要求开源免费,并且可以集成Java生成接口服务。 二、概述 我不做选型对比了,我筛选测试了下Tesseract(v…...