Godot 学习笔记(5):国际化多语言翻译,包含常用10种语言机翻!

news2024/11/29 19:58:04

文章目录

  • 前言
  • 国际化
    • 翻译Api选择
      • 小牛测试
    • 语言选择
    • 代码逻辑
      • 实体对象
      • 翻译帮助类
        • 导出模板
        • 读取文件
        • 翻译
          • 测试
          • 多语言测试
        • 综合翻译
          • 文件准备
          • 测试代码
          • 测试结果
    • 完整代码
      • 实体类
      • 翻译帮助类
      • 网络帮助类
    • 最终效果
      • 翻译前
      • 翻译中
      • 翻译后
  • 总结

前言

为了面向更大的市场,国际化是肯定的。我想如果我开发游戏,至少要支持两种语言,英语和中文简体。

国际化

翻译Api选择

在这里插入图片描述
国内Api也有三种选择,百度,有道和小牛。我这里就选小牛了,比较便宜。

小牛测试

小牛翻译平台

使用PostMan测试成功
在这里插入图片描述

语言选择

在这里插入图片描述
在这里插入图片描述

首先,作为中文为母语,所以我至少支持三种语言。简中,繁中和英语。下面附上小牛的对应参数表

语言参数
简中zh
繁中cht
英语en
德语de
法语fr
西班牙语es
意大利语it
葡萄牙语pt
俄语ru
日语ja
韩语ko

吐槽一下,写了这么多,我都快认不清这个【语】字是什么意思了。

原文选择我这里选择英语作为原文,因为这样可以顺便学一下英语。

代码逻辑

这里使用了MiniExcel
在这里插入图片描述
Json化方式
在这里插入图片描述

实体对象

public class TranslateModel
{
    public TranslateModel() { }

    public TranslateModel(string scene,string key,string en) {
        Scene = scene;
        Key = key;
        EN = en;
    }
    public string Scene { get; set; }

    public string Key { get; set; }

    /// <summary>
    /// 英语
    /// </summary>
    public string EN { get; set; }

    /// <summary>
    /// 简体中文
    /// </summary>
    public string ZH { get; set; }

    


    /// <summary>
    /// 繁体中文
    /// </summary>
    public string CHT { get; set; }


    /// <summary>
    /// 德语
    /// </summary>
    public string DE { get; set; }


    /// <summary>
    /// 法语
    /// </summary>
    public string FR { get; set; }


    /// <summary>
    /// 西班牙语
    /// </summary>
    public string ES { get; set; }


    /// <summary>
    /// 意大利语
    /// </summary>
    public string IT { get; set; }

    /// <summary>
    /// 葡萄牙语
    /// </summary>
    public string PT { get; set; }

    /// <summary>
    /// 俄语
    /// </summary>
    public string RU { get; set; }


    /// <summary>
    /// 日语
    /// </summary>
    public string JA { get; set; }

    /// <summary>
    /// 韩语
    /// </summary>
    public string KO { get; set; }
}

翻译帮助类

public class TranslateHelper
{


/// <summary>
/// 存放读取的数据
/// </summary>
public IEnumerable<TranslateModel> Translates { get; private set; }

            /// <summary>
        /// 模板路径
        /// </summary>
        public readonly string TemplateUrl = "Assests/translate_template.xlsx";

        /// <summary>
        /// 读取路径
        /// </summary>
        public readonly string ReadUrl = "Assests/translate_read.xlsx";

        /// <summary>
        /// 翻译导出路径
        /// </summary>

        public readonly string WriteUrl = "Assests/translate_read.xlsx";

    public TranslateHelper()
    {

    }


}
导出模板
/// <summary>
/// 导出模板,如果文件存在则跳过
/// </summary>
public void CreateTemplate()
{
    if (!File.Exists(TemplateUrl))
    {
        var config = new OpenXmlConfiguration()
        {
            TableStyles = TableStyles.None
        };
        var saveTemplate = new List<TranslateModel>();
        saveTemplate.Add(new TranslateModel("Main", "Hello", "Hello World!"));

        MiniExcel.SaveAs(TemplateUrl, saveTemplate,configuration: config);
    }
}

在这里插入图片描述

读取文件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

翻译

这里用一下我的封装

C# HttpClient Get Post简单封装

先来一个Hello world!翻译

在这里插入图片描述

public class TranslateHelper
{

    public enum Language { zh, cht, en, de, fr, es, it, pt, ru, ja, ko }

    /// <summary>
    /// 存放读取的数据
    /// </summary>
    public IEnumerable<TranslateModel> Translates { get; private set; }

    /// <summary>
    /// 模板路径
    /// </summary>
    public const string TemplateUrl = "Assests/translate_template.xlsx";

    /// <summary>
    /// 读取路径
    /// </summary>
    public const string ReadUrl = "Assests/translate_read.xlsx";

    /// <summary>
    /// 翻译导出路径
    /// </summary>

    public const string WriteUrl = "Assests/translate_read.xlsx";


    public const string API_KEY = "你的key";

    public const string APPID = "你的ip";

    public const string API_URL = "https://api.niutrans.com/NiuTransServer/translation";

    public TranslateHelper()
    {

    }
    /// <summary>
    /// 导出模板,如果文件存在则跳过
    /// </summary>
    public void CreateTemplate()
    {
        if (!File.Exists(TemplateUrl))
        {
            var config = new OpenXmlConfiguration()
            {
                TableStyles = TableStyles.None
            };
            var saveTemplate = new List<TranslateModel>();
            saveTemplate.Add(new TranslateModel("Main", "Hello", "Hello World!"));

            MiniExcel.SaveAs(TemplateUrl, saveTemplate, configuration: config);
        }
    }



    public void Read()
    {
        Translates = MiniExcel.Query<TranslateModel>(ReadUrl);

    }


    public async Task<string> TranslateFromEN(string en, Language language)
    {
    //这个是我自己封装的,你也可以用微软官方的原生httpclient
        var httpHelper = new MyHttpHelper(API_URL);
        var data = new
        {
            src_text = en,
            from = "en",
            to = language.ToString(),
            apikey = API_KEY,
        };
        var res = await httpHelper.JsonHttpPost<Dictionary<string,string>>("", data, null);

        var str = res["tgt_text"];
        return str;
    }


}
测试
        static void Main(string[] args)
        {
            var helper = new TranslateHelper();
            helper.CreateTemplate();
            Console.WriteLine("开始!");

            Task.Run(async () =>
            {
                var res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.zh);
                Console.WriteLine(res);
            });

            Console.WriteLine("结束!");
            Console.ReadKey();
        }

在这里插入图片描述

多语言测试
Task.Run(async () =>
{
    var res = "";
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.zh);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.cht);
    Console.WriteLine(res);

    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.de);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.fr);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.es);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.it);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.pt);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.ru);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.ja);
    Console.WriteLine(res);
    res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.ko);
    Console.WriteLine(res);
});

在这里插入图片描述

综合翻译
/// <summary>
/// 读取并写入机翻结果
/// </summary>
/// <returns></returns>
public async Task ReadAndWrite()
{
    if(!File.Exists(ReadUrl))
    {
        Console.WriteLine($"[{ReadUrl}]文件不存在,读取失败");
        return;
    }
    else
    {
        Translates = MiniExcel.Query<TranslateModel>(ReadUrl).ToArray();
    }

    if (File.Exists(WriteUrl))
    {
        Console.WriteLine($"[{WriteUrl}]文件已存在,跳过翻译");
        return ;

    }
    else
    {
        for(var i = 0;i< Translates.Count();i++)
        {
            Console.WriteLine($"翻译进度:[{i}/{Translates.Count()}]");

            Translates[i] = await TranslateAllFromEN(Translates[i]);
        }
        //将数据保留
        MiniExcel.SaveAs(WriteUrl, Translates);
    }
    
}

/// <summary>
/// 从EN翻译全部
/// </summary>
/// <returns></returns>
public async Task<TranslateModel> TranslateAllFromEN(TranslateModel translateModel)
{
    if (translateModel.EN != null && translateModel.EN != "")
    {
        
        var en = translateModel.EN;
        translateModel.ZH = await TranslateFromEN(en, Language.zh);
        translateModel.CHT = await TranslateFromEN(en, Language.cht);
        translateModel.DE = await TranslateFromEN(en, Language.de);
        translateModel.FR = await TranslateFromEN(en, Language.fr);
        translateModel.ES = await TranslateFromEN(en, Language.es);
        translateModel.IT = await TranslateFromEN(en, Language.it);
        translateModel.PT = await TranslateFromEN(en, Language.pt);
        translateModel.RU = await TranslateFromEN(en, Language.ru);
        translateModel.JA = await TranslateFromEN(en, Language.ja);
        translateModel.KO = await TranslateFromEN(en, Language.ko);
        Console.WriteLine(JsonConvert.SerializeObject(translateModel));
    }
    else
    {
        Console.WriteLine($"Scene[{translateModel.Scene}],Key[{translateModel.Key}]的EN为空");
    }

    return translateModel;
    
}

/// <summary>
/// EN单独翻译
/// </summary>
/// <param name="en"></param>
/// <param name="language"></param>
/// <returns></returns>
public async Task<string> TranslateFromEN(string en, Language language)
{
    //防止请求过快,小牛API并发有限制
    await Task.Delay(100);
    //Console.WriteLine(language.ToString());
    var httpHelper = new MyHttpHelper(API_URL);
    var data = new
    {
        src_text = en,
        from = "en",
        to = language.ToString(),
        apikey = API_KEY,
    };
    var res = await httpHelper.JsonHttpPost<Dictionary<string,string>>("", data, null);

    var str = res["tgt_text"];
    return str;
}
文件准备

在这里插入图片描述

在这里插入图片描述

测试代码
Task.Run(async () =>
{
    await helper.ReadAndWrite();
  
});
测试结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完整代码

实体类

public class TranslateModel
{
    public TranslateModel() { }

    public TranslateModel(string scene,string key,string en) {
        Scene = scene;
        Key = key;
        EN = en;
    }
    public string Scene { get; set; }

    public string Key { get; set; }

    /// <summary>
    /// 英语
    /// </summary>
    public string EN { get; set; }

    /// <summary>
    /// 简体中文
    /// </summary>
    public string ZH { get; set; }

    


    /// <summary>
    /// 繁体中文
    /// </summary>
    public string CHT { get; set; }


    /// <summary>
    /// 德语
    /// </summary>
    public string DE { get; set; }


    /// <summary>
    /// 法语
    /// </summary>
    public string FR { get; set; }


    /// <summary>
    /// 西班牙语
    /// </summary>
    public string ES { get; set; }


    /// <summary>
    /// 意大利语
    /// </summary>
    public string IT { get; set; }

    /// <summary>
    /// 葡萄牙语
    /// </summary>
    public string PT { get; set; }

    /// <summary>
    /// 俄语
    /// </summary>
    public string RU { get; set; }


    /// <summary>
    /// 日语
    /// </summary>
    public string JA { get; set; }

    /// <summary>
    /// 韩语
    /// </summary>
    public string KO { get; set; }
}

翻译帮助类

public class TranslateHelper
{

    public enum Language { zh, cht, en, de, fr, es, it, pt, ru, ja, ko }

    /// <summary>
    /// 存放读取的数据
    /// </summary>
    public TranslateModel[] Translates { get; private set; }

    /// <summary>
    /// 模板路径
    /// </summary>
    public const string TemplateUrl = "Assests/translate_template.xlsx";

    /// <summary>
    /// 读取路径
    /// </summary>
    public const string ReadUrl = "Assests/translate_read.xlsx";

    /// <summary>
    /// 翻译导出路径
    /// </summary>

    public const string WriteUrl = "Assests/translate_write.xlsx";


    public const string API_KEY = "你的key";

    public const string APPID = "你的appid";

    public const string API_URL = "https://api.niutrans.com/NiuTransServer/translation";

    public TranslateHelper()
    {

    }
    /// <summary>
    /// 导出模板,如果文件存在则跳过
    /// </summary>
    public void CreateTemplate()
    {
        if (!File.Exists(TemplateUrl))
        {
            var config = new OpenXmlConfiguration()
            {
                TableStyles = TableStyles.None
            };
            var saveTemplate = new List<TranslateModel>();
            saveTemplate.Add(new TranslateModel("Main", "Hello", "Hello World!"));

            MiniExcel.SaveAs(TemplateUrl, saveTemplate, configuration: config);
        }
        else
        {
            Console.WriteLine($"[{TemplateUrl}]文件已存在,跳过创建");
        }
    }


    /// <summary>
    /// 读取并写入机翻结果
    /// </summary>
    /// <returns></returns>
    public async Task ReadAndWrite()
    {
        if(!File.Exists(ReadUrl))
        {
            Console.WriteLine($"[{ReadUrl}]文件不存在,读取失败");
            return;
        }
        else
        {
            Translates = MiniExcel.Query<TranslateModel>(ReadUrl).ToArray();
        }

        if (File.Exists(WriteUrl))
        {
            Console.WriteLine($"[{WriteUrl}]文件已存在,跳过翻译");
            return ;

        }
        else
        {
            for(var i = 0;i< Translates.Count();i++)
            {
                Console.WriteLine($"翻译进度:[{i+1}/{Translates.Count()}]");

                Translates[i] = await TranslateAllFromEN(Translates[i]);
            }
            var config = new OpenXmlConfiguration()
            {
                TableStyles = TableStyles.None
            };
            //将数据保留
            MiniExcel.SaveAs(WriteUrl, Translates,configuration:config);
        }
        
    }

    /// <summary>
    /// 从EN翻译全部
    /// </summary>
    /// <returns></returns>
    public async Task<TranslateModel> TranslateAllFromEN(TranslateModel translateModel)
    {
        if (translateModel.EN != null && translateModel.EN != "")
        {
            
            var en = translateModel.EN;
            translateModel.ZH = await TranslateFromEN(en, Language.zh);
            translateModel.CHT = await TranslateFromEN(en, Language.cht);
            translateModel.DE = await TranslateFromEN(en, Language.de);
            translateModel.FR = await TranslateFromEN(en, Language.fr);
            translateModel.ES = await TranslateFromEN(en, Language.es);
            translateModel.IT = await TranslateFromEN(en, Language.it);
            translateModel.PT = await TranslateFromEN(en, Language.pt);
            translateModel.RU = await TranslateFromEN(en, Language.ru);
            translateModel.JA = await TranslateFromEN(en, Language.ja);
            translateModel.KO = await TranslateFromEN(en, Language.ko);
            Console.WriteLine(JsonConvert.SerializeObject(translateModel));
        }
        else
        {
            Console.WriteLine($"Scene[{translateModel.Scene}],Key[{translateModel.Key}]的EN为空");
        }

        return translateModel;
        
    }

    /// <summary>
    /// EN单独翻译
    /// </summary>
    /// <param name="en"></param>
    /// <param name="language"></param>
    /// <returns></returns>
    public async Task<string> TranslateFromEN(string en, Language language)
    {
        //防止请求过快,小牛API并发有限制
        await Task.Delay(100);
        //Console.WriteLine(language.ToString());
        var httpHelper = new MyHttpHelper(API_URL);
        var data = new
        {
            src_text = en,
            from = "en",
            to = language.ToString(),
            apikey = API_KEY,
        };
        var res = await httpHelper.JsonHttpPost<Dictionary<string,string>>("", data, null);

        var str = res["tgt_text"];
        return str;
    }


}

网络帮助类

public class MyHttpHelper
{

    private string baseUrl;


    /// <summary>
    /// 基础Api
    /// </summary>
    public string BaseUrl
    {
        get
        {
            return baseUrl;
        }

        set
        {
            baseUrl = value;
            MyHttpClient = new HttpClient()
            {
                BaseAddress = new Uri(baseUrl)
            };
        }
    }


    public HttpClient MyHttpClient { get; set; }
    public MyHttpHelper()
    {

    }

    public MyHttpHelper(string baseUrl)
    {
        BaseUrl = baseUrl;
    }

    /// <summary>
    /// 序列化返回值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="api"></param>
    /// <param name="strParams"></param>
    /// <returns></returns>
    public async Task<T> JsonHttpGet<T>(string api, Dictionary<string, string> strParams)
    {
        var res = await MyHttpGet(api, strParams);
        return await res.Content.ReadFromJsonAsync<T>();
    }


    /// <summary>
    /// 序列化返回值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="api"></param>
    /// <param name="value"></param>
    /// <param name="strParams"></param>
    /// <returns></returns>
    public async Task<T> JsonHttpPost<T>(string api, object value, Dictionary<string, string> strParams)
    {
        var res = await MyHttpPost(api, value, strParams);
        return await res.Content.ReadFromJsonAsync<T>();
    }

    /// <summary>
    /// 序列化请求
    /// </summary>
    /// <param name="api"></param>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<HttpResponseMessage> MyHttpGet(string api, Dictionary<string, string> param)
    {
        string paramStr = DictionaryToParams(param);
        return await MyHttpClient.GetAsync(api + paramStr);
    }

    /// <summary>
    /// 自定义的转发功能
    /// </summary>
    /// <param name="api"></param>
    /// <param name="dataname"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public Task<HttpResponseMessage> MyHttpPost(string api, object value, Dictionary<string, string> strParams)
    {
        return MyHttpClient.PostAsync(api + DictionaryToParams(strParams), new StringContent(JsonConvert.SerializeObject(value), Encoding.UTF8, "application/json"));
    }

    /// <summary>
    /// 字典转参数
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public string DictionaryToParams(Dictionary<string, string> param)
    {
        var res = "";
        if (param != null)
        {
            var list = param.ToList();
            if (list.Count != 0)
            {
                for (var i = 0; i < list.Count; i++)
                {

                    if (i != 0)
                    {
                        res += "&";
                    }
                    res += $"{list[i].Key}={list[i].Value}";
                }
                res = "?" + res;
            }

        }
        return res;
    }
}

最终效果

翻译前

在这里插入图片描述

翻译中

在这里插入图片描述

翻译后

在这里插入图片描述

总结

多语言发布,这样可以让我们的游戏在更多的国家用户使用。虽然我暂时没有这个需求,但是说不定也有别的项目需要多语言的本地化接入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1556051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【开发篇】六、查询大量数据导致内存溢出

文章目录 1、溢出场景2、快照文件分析3、本地环境复现4、结论5、解决思路 记录一个问题&#xff0c;工作中有个数据处理服务OOM&#xff0c;查了下镜像的dockerfile&#xff0c;发现JVM参数如下。很明显&#xff0c;一个数据服务&#xff0c;里面经手大量的数据对象&#xff0c…

探究分布式事务:深入ACID特性在分布式系统中的挑战与解决方案

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…

并发编程之CountDownLatch和CyclicBarrier的详细解析(带小案例)

CountDownLatch 倒计时锁存器 用来解决线程执行次序的问题 CountDownLatch主要有两个方法&#xff0c;当一个或多个线程调用await方法时&#xff0c;这些线程会阻塞。 其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞)&#xff0c; 当计数器的值变为…

B096-docker版jenkins环境搭建

目录 Jenkins持续集成工具的介绍Jenkins安装过程案例 tips&#xff1a;ssm项目需要放到tomcat中运行&#xff0c;springboot项目不需要&#xff0c;内置有tomcat&#xff0c;可直接命令行运行 Jenkins持续集成工具的介绍 Jenkins安装过程 docker版Jenkins需要先安装docker环境…

三个对象组练习.java

题目&#xff1a;定义数组存储3部汽车对象&#xff1b;汽车属性&#xff1a;品牌&#xff0c;价格&#xff0c;颜色&#xff1b;创造3个汽车对象&#xff0c;数据通过键盘录入而来&#xff0c;并把数据存储到数组当中 分析&#xff1a; 在main&#xff08;&#xff09;里面定义…

npm ERR! errno CERT_HAS_EXPIRED

1 问题描述 使用npm命令安装相关依赖报错&#xff1a;npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/vue%2fcli failed, reason: certificate has expired报错示例图如下所示&#xff1a; 2原因分析…

实验室开放项目实验报告-01

实验室开放项目实验报告 实验名称&#xff1a;实验一输入输出格式 实验目的&#xff1a;熟练掌握程序设计竞赛中通常采用的输入输出格式和掌握不同格式输入输出数据的处理方法 实验内容&#xff1a; 在本地电脑中新建一个文件夹&#xff0c;用于存放C源程序&#xff0c;文件…

学习鸿蒙基础(9)

目录 一、鸿蒙国际化配置 二、鸿蒙常用组件介绍 三、鸿蒙像素单位介绍 四、鸿蒙布局介绍 1、Row与Column线性布局 2、层叠布局-Stack 3、弹性布局 4、栅格布局 5、网格布局 一、鸿蒙国际化配置 base目录下为默认的string。en_US对应美国的。zh_CN对应中国的。新增一个s…

[RAM] 图解 RAM 结构原理

主页&#xff1a; 元存储博客 文章目录 前言1. Channel2. Dimm3. Rank4. Bank5. Row6. Column7. Beat8. Burst Length总结 前言 从CPU至DRAM晶粒之间依据层级由大至小为channel>DIMM>rank>chip>bank>row/column。 图片来源&#xff1a; 电脑王 DRAM层级关系 DR…

应急响应靶机训练-Linux1题解

前言 接上文&#xff0c;应急响应靶机训练Linux1 靶机地址&#xff1a; 应急响应靶机-Linux(1) 最近感冒了&#xff0c;就没录视频版。 题解 目标&#xff1a;3个flag以及黑客的ip地址 登陆虚拟机 密码defend flag1: su history flag{thisismybaby} flag2&#xff1a;…

AI Agent智能应用从0到1定制开发 (包含全部教学视频和全部源码,附链接)

链接分享&#xff1a;https://pan.baidu.com/s/1Cjk-MNDY4DYQKvNI1L4Tzg?pwd3vcd 提取码:3vcd 全部教学视频和全部源码链接分享在下方。 第1章&#xff1a;多模型强应用&#xff1a;AI2.0时代应用开发者机会 在AI2.0时代&#xff0c;应用开发者面临着前所未有的机遇。这一章…

盘点最适合做剧场版的国漫,最后一部有望成为巅峰

最近《完美世界》动画官宣首部剧场版&#xff0c;主要讲述石昊和火灵儿的故事。这个消息一出&#xff0c;引发了很多漫迷的讨论&#xff0c;其实现在已经有好几部国漫做过剧场版&#xff0c;还有是观众一致希望未来会出剧场版的。那么究竟是哪些国漫呢&#xff0c;下面就一起来…

源支付 V7 版,150购买,需要的下载研究,拿走回复

源支付 V7 版&#xff0c;150购买&#xff0c;需要的下载研究,拿走回复 来自站长论坛搬砖&#xff0c;站长论坛搬砖&#xff0c;站长论坛搬砖&#xff0c;站长论坛搬砖&#xff0c;下载地址在最后 请按官方教程配置&#xff0c;专为个人站长打造的聚合免签系统&#xff0c;拥有…

视频监控平台和视频接入网关,支持HTTPS实现视频浏览和录像回放

目录 一、https协议介绍 &#xff08;一&#xff09;什么叫https &#xff08;二&#xff09;https的工作原理 &#xff08;三&#xff09;https和http的区别 二、视频监控平台为何要采用https &#xff08;一&#xff09;采用HTTPS浏览视频的好处体现在以下几个方面&…

手撕算法-跳跃游戏

描述 分析 如果某一个作为 起跳点 的格子可以跳跃的距离是 3&#xff0c;那么表示后面 3 个格子都可以作为 起跳点可以对每一个能作为 起跳点 的格子都尝试跳一次&#xff0c;把 能跳到最远的距离 不断更新如果可以一直跳到最后&#xff0c;就成功了 代码 class Solution {…

使用Leaflet.rotatedMaker进行航班飞行航向模拟的实践

目录 前言 一、Leaflet的不足 1、方向插件 2、方向控制脚本说明 二、实时航向可视化实现 1、创建主体框架 2、飞机展示 3、位置和方位模拟 三、成果及分析 1、成果展示 2、方向绑定解读 总结 前言 众所周知&#xff0c;物体在空间中的运动&#xff08;比如飞行、跑步…

【JAVA】Idea 右侧的gradle 不见了

1. 找到项目的build.gradle 文件&#xff0c;右键 2. 找到“Link Gradle Project”选项 3. 右侧就出现了gradle

通过node 后端实现颜色窃贼 (取出某个图片的主体rgb颜色 )

1.需求 我前端轮播图的背景色 想通过每一张轮播图片的颜色作为背景色 这样的话 需要通过一张图片 取出图片的颜色 这个工作通过前端去处理 也可以通过后端去处理 前端我试了试 color-thief 的插件 但是 这个插件是基于canvas 的模式来的 我需要在小程序中使用这个插件 而且是…

大规模云存储展望|2024逐步复苏,2025全面恢复

SSD以其高速度和低延迟等优点&#xff0c;尤其在容量增长和每GB成本降低方面&#xff0c;SSD的增长速度预计将超过近线硬盘&#xff08;Nearline HDD&#xff09;。尽管HDD在大容量存储方面仍有一定优势&#xff0c;但由于SSD在访问速度、能耗及体积等方面的突出表现&#xff0…

macOS系统配置RUST开发环境

打开rust语言官方网,然后点击马上开始: Rust 程序设计语言 配置RUST开发环境: 使用curl下载rust安装脚本: 复制到终端执行: curl --proto =https --tlsv1.2 -sSf https://sh.rustup.rs | sh 输入: y 选择默认安装,输入: 1