https://seaony.github.io Seaony' Blog 2023-04-21T11:50:31.209Z https://github.com/jpmonette/feed 一定要有所失,才能有所悟吗? https://seaony.github.io/images/avatar.png https://seaony.github.io/favicon.ico All rights reserved 2023, Seaony' Blog <![CDATA[🎃 小李是中国人 (单词 + 语法)]]> https://seaony.github.io/post/di-yi-ke/ 2023-04-20T15:46:31.000Z 🧶 基本单词
  • ちゅうごくじん (4)

    词义:中国人

  • にほんじん (4)

    词义:日本人

  • かんこくじん (4)

    词义:韩国人

  • あめりかじん (4)

    词义:美国人

  • ふらんすじん (4)

    词义:法国人

  • がくせい (0)

    词义:学生

  • りゅうがくせい (3)

    词义:留学生

  • きょうじゅ (0)

    词义:教授

  • しゃいん (1)

    词义:职员

  • かいしゃいん (3)

    词义:公司职员

  • てんいん (0)

    词义:店员

  • けんしゅうせい (3)

    词义:进修生

  • きぎょう (1)

    词义:企业

  • だいがく (0)

    词义:大学

  • ちち (1/2)

    词义:父亲

  • かちょう (0)

    词义:科长

  • しゃちょう (0)

    词义:总经理

  • でむかえ (0)

    词义:迎接

  • あのひと (2)

    词义:那个人

  • わたし (0)

    词义:我

  • あなた (2)

    词义:你

  • どうも (1)

    词义:非常、很

  • はい (1)

    词义:是的

  • いいえ (3)

    词义:不,不是

  • あつ

    词义:哎,哎呀

  • 词义:李

  • おう (1)

    词义:王

  • ちょ (1)

    词义:张

  • もり (0)

    词义:森

  • はやし (0)

    词义:林

  • おの (0)

    词义:小野

  • よしだ (0)

    词义:吉田

  • たなか (0)

    词义:田中

  • なかむら (0)

    词义:中村

  • たろう (1)

    词义:太郎

  • キム (1)

    词义:金

  • でゅぽん (1)

    词义:ヂュポン (迪蓬)

  • すみす (1)

    词义:スミス/斯密斯

  • じょんそん (1)

    词义:ジョンソn/约翰逊

  • ちゅうごく (1)

    词义:中国

  • とうきょうだいがく (1)

    词义:東京大学

  • ぺきんだいがく (1)

    词义:北京大学

  • ジェーシーきかく (1)

    词义:JC策划公司

  • ぺきんりょにうしゃ (5)

    词义:北京旅行社

  • にちゅうしょうじ (5)

    词义:日中商事

  • こっにちは (5)

    词义:你好

  • すみません (4)

    词义:对不起

  • どんぞ (1)

    词义:请

  • 〜さん、くん

    词义:先生、小姐

  • はじめまして (4)

    词义:初次见面

  • こちらこそ (4)

    词义:我才要 (请您)

  • そうです (1)

    词义:是 (这样)

  • ちがいます (4)

    词义:不是

  • わかりません (5)

    词义:不是


🍻 语法

  1. 名は 名です (AはBです)

    相当于汉语的 “~是~”。“~は” 是主语部分,“です” 是谓语部分。

    助词 “は” 用于提示主题,读作 “わ”。

    ▲ 李さんは 中国人です。(小李是中国人。)

    ▲ わたしは 日本人です。(我是日本人。)

    ▲ わたしは 王です。(我姓王。)

    ▲ わたしは がくせんです。私は 学生です。(我是学生。)

  2. 名は 名ではありません (AはBではありません)

    相当于汉语 “~不是~”。“では ありません” 的 “では” 在口语中有时候会发成 “じゃ”

    ▲ 森さんは 学生ではありません。(森先生不是学生。)

    ▲ わたしは 日本人ではありません。(我不是日本人。)

    ▲ わたしわ 田中じゃありません。(我不是田中。)

    ▲ 私わ 小学生では ありません(我不是小学生。)

  3. 名は 名ですか (AはBですか)

    相当于汉语的 “~是~吗?”

    助词 “か” 接在句尾表示疑问。日语的问句在句尾不使用 “?”。

    回答是可以只用 “はい” 或 “いいえ”。

    ▲ あなたは小野さんですか。(您是小野女士吗?)
    ーーはい、小野です。(是的,我是小野。)

    ▲ キムさん中国人ですか。(金女士是中国人吗?)
    ーーいいえ、中国人では ありますん。(不,不是中国人)

  4. 名の名 [从属机构、国家][属性] (AのB)

    一般情况下相当于汉语的 “的” 的意思。

    助词 “の” 连接名词和名词,表示前面的名词是后面名词从属的机构、国家或属性。

    ▲ 李さんはJC区画の社員。(小李是JC策划公司的职员)

    ▲ 北京旅行社は中国の企画です。(北京旅行社是中国的企业)

👨‍💻 表达语及词语

  1. 人称

    • “わたし”、“あなた”、“あの人”

    • “~さん”

  2. 省略

  3. あっ [叹词]

  4. どうぞ、よろしく お願いします [多多关照]

]]>
<![CDATA[🚍 日语声调 - [日语学习笔记]]]> https://seaony.github.io/post/ri-yu-sheng-diao-ri-yu-xue-xi-bi-ji/ 2023-04-20T14:17:56.000Z 🫠 什么是声调

日语词语中的各个音节之间存在的高低、轻重的配置关系叫做声调(アクセント),声调可以用来区分同音词。与中文的四声声调不同,日语是高低型声调,发音是“由低到高”“由高到低”的状态,单词中某些音节为高音,某些音节为低音。


🧶 声调规则

  1. 第一个音与第二音不是同音

  2. 出现降音就不会升回去

  3. 在第几个音出现,就是几型


🪴 声调类型

日语的声调可以分为平板型和起伏型,起伏型又分为头高型、中高型、尾高型。

  1. 平板型

    第一个音节低,后面音都高。后续助词为高音,这种类型中由三至四个音节组成的词较多。

  2. 头高型

    第一个音节高,后面音都低。

  3. 中高型

    第一个和最后一个音节低,中间为高音(分全为高音节和部分为高音节)。后续助词为低音这种类型中没有一个或两个音节的词,三个音节以上才会出现。

  4. 尾高型

    第一个音节低,第二个音开始都为高音节。后续助词为低音。

在日语中一个假名代表一拍,包括表示清音、浊音、半浊音、促音っ、拨音ん以及长音的假名,但是不包括组成拗音中的小“ゃ”、“ゅ”和“ょ”,即一个拗音整体上作为一个音拍来看待,如“きゃ”是一个音拍,而不是两拍。而“きょう”和“そう”等长音则是两拍。


🍻 长音规则

  1. “あ”、“い”、“う”段假名分别在其后加“あ”、“い”、“う”构成长音。

  2. “え”段假名在其后加“い”构成长音。但是个别单词中也有加“え”的。

  3. “お”段假名在其后加“う”构成长音。但是个别单词中也有加“お”的。

  4. 用片假名书写的外来语用长音符号“一”来表示。

  5. 用罗马字标记时,既可以在元音上标注“一”来表示长音,也可以通过双写元音字母来表示长音。

あ段假名后加あ,如:おかあさんい段假名后加い,如:おにいさんう段假名后加う,如:つうやくえ段假名后加い,如:せんせいお段假名后加う,如:おとうさん外来语长音用ー表示:如:ノート 另外,特殊场合下:え段假名后加え,如:おねえさんお段假名后加お,如:おおきい。

]]>
<![CDATA[🎃 iOS Swift 项目实现多语言支持]]> https://seaony.github.io/post/ios-swift-xiang-mu-shi-xian-duo-yu-yan-zhi-chi/ 2023-04-16T11:11:43.000Z 😶‍🌫️ 创建文件

在项目根目录下右键选择 New File,创建一个名为 Localizable.strings 的 Strings File。

Localizable.strings 中添加你的多语言文本,它看起来就像这样。

// 示例文本
ExampleMessage = "Example Message";

🪴 使用文本

接下来,你可以像这样使用它:

/// - NSlocalizedString
NSlocalizedString("ExampleMessage", comment: "")
 // Example Message

 /// - R.swift
 R.string.localizable.exampleMessage()
  // Example Message

👨‍💻 启用国际化

选中项目 Project Info,在 Localizations 中点击加号,添加你想要支持的语言。


📚 App 名称国际化

创建 InfoPlist.strings 文件,点击右侧 localize,然后选择对应的语言。

接着在文件中设置对应语言的 App 名称:

CFBundleName="Your App Name"
]]>
<![CDATA[🧶 自建 StableDiffusion 流程分享]]> https://seaony.github.io/post/zi-jian-stablediffusion-liu-cheng-fen-xiang/ 2023-04-15T04:34:04.000Z

"The development of full artificial intelligence could spell the end of the human race." - Stephen Hawking


因为 ChatGPT 的原因,最近各种 AI 概念真的很火 XD。

自己手头也正好有一台主机闲置,正好自建一个 StableDiffusion 来玩。

这篇文章可能会持续更新 (如果我有时间),我会在这篇文章中分享整个过程。


💭 部署背景

因为平时会玩游戏,所以主机环境为 Windows10。

加上硬盘也不大,懒得去搞 Ubuntu 双系统了。所以目前的想法是直接部署一套 WebUI,

开放给同局域网下的 Mac 使用。这样主机就可以开着不管,所有操作都使用 Mac 完成。

跑完后再去 Windows 下提取跑出来的图片。

顺带一提,Windows 和 Mac 文件互通确实是件很头疼的事情...


🪴 主机配置

  • CPU: Intel 12700KF

  • 内存: 32G 双通道 DDR4

  • 显卡:RTX 3080 10G DDR6X

  • ... (更多的就懒得写了,和 SD 基本也没太多关系)

如果显卡显存低于 4G 可能会比较吃力 🫠,建议使用 Google Colab 这类云服务来跑渲染。


🍻 部署 StableDiffusion

因为我真的很讨厌 Windows 下的编程环境,一点都不想在 Windows 下折腾。

所以我直接用了比较成熟的 WebUI: AUTOMATIC1111/stable-diffusion-webui

当然,如果喜欢折腾的话也可以自己去 Clone 源码编译用 Shell 跑。

整个安装过程还是比较简单的,跟着 README 走即可。

  1. 安装 Python 和 Git. (Python 要记得加 Path)。

  2. Clone WebUI 到本地 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git

  3. 打开 Clone 下来的项目文件夹,双击 webui-user.bat 启动。

第一次运行需要安装对应的依赖和库,一般需要等 20 ~ 30 分钟。同时,你需要科学上网。

等待安装完成启动后,访问 127.0.0.1.7860 即可使用。


🍓 常见问题

遇到问题可以先查阅官方提供的 Wiki

1. 主机服务开放局域网访问

为了使局域网内的电脑可以访问本机服务,你可以做以下设置:

  1. 关闭 Windows 防火墙

    设置 - Windows 安全中心 - 防火墙和网络保护 中关闭你的防火墙。

    当然,这种方法其实是有一定风险的,你也可以使用 添加入站规则的方式

  2. 修改 StableDiffusionWebUI 启动参数

    使用文本编辑工具打开 WebUI 目录下的 webui-user.bat,添加如下参数:

    set COMMANDLINE_ARGS=--listen --share --no-gradio-queue --enable-insecure-extension-access
    

    前两个参数是为了局域网可以正常访问服务,后两个参数解决非本机无法安装拓展的问题。

2. WebUI 用户界面的汉化

虽然全是名词,但是汉化成中文还是用起来会方便一些。

直接安装这个 Extension 即可完成汉化:VinsonLaro/stable-diffusion-webui-chinese

顺带一提,使用 Chinese-English 会更好一些,有些名词翻译后还是比较迷惑的。

]]>
<![CDATA[🪴 绕过 Cloudflare 访问 Valorant Api]]> https://seaony.github.io/post/laravel-rao-guo-cloudflare-fang-huo-qiang-fang-wen-valorant-nei-bu-api/ 2023-04-06T18:46:08.000Z

本文章所实现内容仅做学习分享所用,本人不承担任何责任,请勿将相关信息用于非法用途。

🫠 准备工作

首先,安装 GuzzleHttp 网络请求 Package。

composer require guzzlehttp/guzzle

💭 绕过 Cloudflare

Valorant Api 受到 Cloudflare 防护,以及 Riot 也加了一层验证。

绕过 Cloudflare 的核心原理是使用 Ciphers 伪造 SSL,具体请求方式如下:

 /**
* 用于绕过 Riot 防护的请求头
*
* @var string[] 请求头
*/
$headers = [
    'Content-Type'          => 'application/json',
    'User-Agent'            => 'RiotClient/63.0.5.4887690.4789131 rso-auth (Windows; 10;;Professional, x64)',
    'X-Riot-ClientPlatform' => 'ew0KCSJwbGF0Zm9ybVR5cGUiOiAiUEMiLA0KCSJwbGF0Zm9ybU9TIjogIldpbmRvd3MiLA0KCSJwbGF0Zm9ybU9TVmVyc2lvbiI6ICIxMC4wLjE5MDQyLjEuMjU2LjY0Yml0IiwNCgkicGxhdGZvcm1DaGlwc2V0IjogIlVua25vd24iDQp9',
];

/**
* 请求中绕过 Cloudflare 所需要的 SSL 证书加密方式
*
* @var string[] 用于请求的参数
*/
$ciphers13 = [
    'TLS_CHACHA20_POLY1305_SHA256',
    'TLS_AES_128_GCM_SHA256',
    'TLS_AES_256_GCM_SHA384',
];

/**
* 请求中绕过 Cloudflare 所需要的 SSL 证书加密方式
*
* @var string[] 用于请求的参数
*/
$ciphers = [
    'ECDHE-ECDSA-CHACHA20-POLY1305',
    'ECDHE-RSA-CHACHA20-POLY1305',
    'ECDHE-ECDSA-AES128-GCM-SHA256',
    'ECDHE-RSA-AES128-GCM-SHA256',
    'ECDHE-ECDSA-AES256-GCM-SHA384',
    'ECDHE-RSA-AES256-GCM-SHA384',
    'ECDHE-ECDSA-AES128-SHA',
    'ECDHE-RSA-AES128-SHA',
    'ECDHE-ECDSA-AES256-SHA',
    'ECDHE-RSA-AES256-SHA',
    'AES128-GCM-SHA256',
    'AES256-GCM-SHA384',
    'AES128-SHA',
    'AES256-SHA',
    'DES-CBC3-SHA',  # most likely not available
];

// 实例化 HttpClient
 $client = new \GuzzleHttp\Client([
    'cookies' => true, // 开启 Cookie,保存 Riot 返回的 Token
    'curl'    => [
        CURLOPT_SSLVERSION      => CURL_SSLVERSION_TLSv1_3,
        CURLOPT_SSL_CIPHER_LIST => implode(':', $ciphers),
        CURLOPT_TLS13_CIPHERS   => implode(':', $ciphers13),
    ],
]);

// 发送请求
$response = $client->request('POST', 'https://auth.riotgames.com/api/v1/authorization', [
    'json' => [
        'client_id'             => 'riot-client',
        'code_challenge'        => '',
        'code_challenge_method' => '',
        'acr_values'            => '',
        'claims'                => '',
        'nonce'                 => '69420',
        'redirect_uri'          => 'http://localhost/redirect',
        'response_type'         => 'token id_token',
        'scope'                 => 'openid link ban lol_region',
    ],
]);

// do something

👨‍💻 Reference Links

]]>
<![CDATA[👨‍💻 iOS 项目中使用自定义字体]]> https://seaony.github.io/post/ios-xiang-mu-zhong-dao-ru-zi-ding-yi-zi-ti/ 2023-03-27T21:33:25.000Z 🪴 全局加载字体

1. 导入字体文件

准备好要使用的字体文件,并且将它导入至你的 XCode Project 中。

Tips:一定要勾选 Copy items if needed ,不勾选的话只会进行位置引用。


2. 修改 Info.plist

打开你的 Info.plist 文件,新增一项:Fonts provided by application

对应的值即为你的字体文件的名称 (不需要带 Group 前缀,需要带文件后缀)。


3. 添加资源文件

确保你的字体文件已添加至 TARGETS - Build Phases - Copy Bundle Resources 中。

一般导入字体文件后会自动添加,但也会有意外 😃


4. 确认导入成功

运行这段代码即可打印出所有可用字体,检查是否导入成功。

for fontFamily in UIFont.familyNames {
    print(fontFamily)

    for font in UIFont.fontNames(forFamilyName: fontFamily) {
        print(fontFamily + ": " + font)
    }
}

🧐 覆盖默认字体

如果你需要全局都显示某个字体,那么就需要这样设置。

如果不这样做,那么你需要在每一个显示文本的地方都指定 FontName

Tips:使用覆盖 UIFont 的方式设置全局字体会导致键盘等系统 UI 字体也被替换。

1. 创建 UIFont 拓展

Extension Group 下创建 UIFontExtension 文件拓展 UIFont 类。

当然,你也可以放在别的位置,使用其他名称 🫠。

import UIKit

// MARK: - AppFontName
struct AppFontName {
    static let italic = "Montserrat-Medium"
    static let regular = "Montserrat-Medium"
    static let semibold = "Montserrat-SemiBold"
    static let bold = "Montserrat-Bold"
    static let heavy = "Montserrat-ExtraBold"
    static let black = "Montserrat-Black"
}

// MARK: - UIFontDescriptor.AttributeName
extension UIFontDescriptor.AttributeName {

    /// NSCTFontUIUsageAttribute
    static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")

}

/// 字体扩展
extension UIFont {

    /// 是否已经替换过
    static var isOverrided: Bool = false

    // 重写系统字体
    @objc class func mySystemFont(ofSize size: CGFloat, weight: UIFont.Weight) -> UIFont {
        switch weight {
        case .ultraLight, .thin, .light, .regular, .medium:
            return UIFont(name: AppFontName.regular, size: size)!
        case .semibold:
            return UIFont(name: AppFontName.semibold, size: size)!
        case .bold:
            return UIFont(name: AppFontName.bold, size: size)!
        case .heavy:
            return UIFont(name: AppFontName.heavy, size: size)!
        case .black:
            return UIFont(name: AppFontName.black, size: size)!
        default:
            return UIFont(name: AppFontName.regular, size: size)!
        }
    }

    // 重写粗体字体
    @objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: AppFontName.bold, size: size)!
    }

    // 重写斜体字体
    @objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: AppFontName.italic, size: size)!
    }

    // 重写字体的编码方法
    @objc convenience init(myCoder aDecoder: NSCoder) {
        guard
                let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor,
                let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String
        else {
            self.init(myCoder: aDecoder)
            return
        }
        var fontName = ""
        switch fontAttribute {
        case "CTFontRegularUsage":
            fontName = AppFontName.regular
        case "CTFontEmphasizedUsage", "CTFontBoldUsage":
            fontName = AppFontName.bold
        case "CTFontObliqueUsage":
            fontName = AppFontName.italic
        default:
            fontName = AppFontName.regular
        }
        self.init(name: fontName, size: fontDescriptor.pointSize)!
    }

    /// 替换系统字体
    class func overrideInitialize() {

        // 避免 method swizzling 运行两次
        guard self == UIFont.self, !isOverrided else {
            return
        }

        // 避免 method swizzling 运行两次并恢复到原始初始化函数
        isOverrided = true

        // 替换系统字体
        if let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:weight:))),
           let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:weight:))) {
            method_exchangeImplementations(systemFontMethod, mySystemFontMethod)
        }

        // 替换粗体字体
        if let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))),
           let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:))) {
            method_exchangeImplementations(boldSystemFontMethod, myBoldSystemFontMethod)
        }

        // 替换斜体字体
        if let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:))),
           let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:))) {
            method_exchangeImplementations(italicSystemFontMethod, myItalicSystemFontMethod)
        }

        // Trick to get over the lack of UIFont.init(coder:))
        if let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))),
           let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:))) {
            method_exchangeImplementations(initCoderMethod, myInitCoderMethod)
        }
    }
}

2. 覆盖初始化方法

在你的 AppDelegate 文件中注册如下方法,覆盖 UIFont 初始化。

override init() {
    super.init()
    UIFont.overrideInitialize()
}

🫠 Reference Links

]]>
<![CDATA[🪴 Xcode 中创建纯代码布局项目]]> https://seaony.github.io/post/hello-gridea/ 2023-03-22T16:03:28.000Z 🧐 1. 移除 Storyboard

没什么好说的,既然是纯代码布局,那么 Storyboard 文件就不需要了。

rm ./Main.storyboard

👨‍💻 2. 修改 Main Interface

因为 Xcode 版本更新,不同的版本会有不同的处理方案。

  • Xcode Version < 14.0

    清空 General - Deployment Info - Main Interface

  • Xcode Version >= 14.0

    清空 Build Setting - UIKit Main Storyboard File Base Name


🪴 3. 设置默认 View

在你的 AppDelegate.swift - application 中添加如下代码。

// 设置默认显示的界面
let controller = YourDefaultViewController()
        
self.window = UIWindow(frame: UIScreen.main.bounds)
window!.rootViewController = UINavigationController(rootViewController: controller)
window?.makeKeyAndVisible()
]]>