博客

  • Switch lan-play原理

    Switch的机器要是被ban了(原因可能有很多,比如买了淘宝数字版。。。),最大的问题就是不能联网了,但是部分游戏是支持局域网联机和当面联机的,所以理论上是可以一起玩的。

    lan-play的作用就是可以让大家在网络环境下也做到当面联机或者局域网联机的效果,这样足不出户就可以和朋友联机。

    由于最近用lan-play老是炸岛,所以花时间看了下大致原理。lan-play大体工作原理如下:

    其中电脑运行了lan-play client,它会和私服链接。而你的Switch需要和电脑链接同一个路由器。

    Switch和lan-play client的通讯

    Switch和lan-play client在一个路由下,而Switch上配置的IP和Gateway地址配置了10.31.XX.XX和10.13.37.1,但是实际上lan-play并没有在这个IP提供服务,而是通过pcap监听相关的包,这就是为什么安装lan-play的第一步是安装pcap。

    pcap是一个抓包工具,支持协议比较广泛,包括

    • Ethernet, Linux SLL, raw IP, PPP (RFC1661, RFC1662), BSD (Mac OS X) loopback encapsulation, and Radiotap
    • IEEE 802.11
    • Probe Request
    • LLC and SNAP
    • IEEE802.1Q
    • ARP
    • IPv4 (RFC791 and RFC1349) and
  • Switch开发环境搭建

    如果由于各种原因需要在Switch上做开发,那么第一个需要的就是环境配置。目前主要需要的是devkitA64和libnx。

    devKitA64是在devkitPro下的,另外还有ARM、3ds等,如果只是Switch开发安装A64即可。这里注意下devkitPro没有版本号管理一说。

    Mac

    我这里以mac为例,首先下载devkitPro_pacman,按照说明安装。然后确认下xcode情况

    xcode-select --install

    修改环境配置为

    export DEVKITPRO=/opt/devkitpro
    export DEVKITARM=${DEVKITPRO}/devkitARM
    export DEVKITPPC=${DEVKITPRO}/devkitPPC
    export PATH=${DEVKITPRO}/tools/bin:$PATH

    libnx在上面安装完成后会自带,不需要额外处理。

    Ubuntu

    如果是ubuntu系统,安装步骤基本一致,首先确保依赖

    apt-get git wget install libxml2 libstdc++6 gpg xz-utils make -y

    安装pacman并设置环境变量

    wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb
    RUN dpkg -i devkitpro-pacman.deb && dkp-pacman -S
  • Github Action使用私有Runner

    Github Action使用私有Runner

    Github Action对于私有库是有一定的分钟数限制,当然如果升级账号可以获得更长时长。

    考虑到有一个空余服务器,且CI对于环境要求没有太高,普通的linux即可。Github Action文档提供了完善的接入说明,对于Windows、Linux、MacOS都支持。

    考虑到方便和隔离,决定在Docker中运行,网上有别人打包好的,直接使用即可。在配置界面找到自己的token,然后运行。

    docker run --name your-runner -e GITHUB_REPOSITORY="github address" \
      -e GITHUB_TOKEN="your token" \
      -e RUNNER_NAME="your-runner" \
      -e REPLACE_EXISTING_RUNNER="true" \
      htynkn/github-action-runner

    在Github上可以看到新的Runner信息

    workflow中修改runs-on为self-hosted就可以了

    runs-on: self-hosted
  • Github Action加密文件的处理

    GitHub Action提供了对于Secrets的支持,可以保存常见的私密信息,比如API_TOKEN等信息,但是对于有些场景还需要私密文件的支持,比如Flutter打包Android APK的时候需要两个文件,一个是key.jks,另外一个是相关配置,一般为key.properties或者放在local.properties中。

    这种情况可以先本地加密需要的文件,然后在Github Action中解密,解密所需的信息放在Github Action Secrets即可。

    这里使用gpg AES256进行加密,指令如下:

    gpg --symmetric --cipher-algo AES256 key.properties

    加密的时候输入秘钥,并配置在Github Action Secrets中。将加密好的文件放在.github目录中,并创建解密用的脚本

    #!/bin/sh
    
    # Decrypt the file
    gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" \
    --output $GITHUB_WORKSPACE/android/key.properties $GITHUB_WORKSPACE/.github/secrets/key.properties.gpg
    
    echo "Decrypt key.properties done"
    
    gpg --quiet --batch --yes 
  • Flutter中的IoC

    因为长期做后端开发,Spring提供的IoC功能确实用的很多。到了Flutter中各种依赖项目的管理也很麻烦,也影响单元测试的编写。

    所以在Flutter还是希望延续平时的习惯,使用IoC去控制依赖等关系。但是Flutter中有一些特殊的情况,比如Flutter禁用了dart:mirrors,反射的使用上有一些问题。对比了几个框架,最开始考虑的是Google下面的inject.dart,但是文档这块比较缺,还有就是注解+代码生成的方式强大,但是不是很喜欢,也用不了这么强的功能。由于名字的原因也看了下ioc库(https://pub.dev/packages/ioc),对于API的语法不是很喜欢。最后选择使用GetIt。

    使用上比较简单,引用依赖

    dependencies:
      get_it: ^3.1.0

    代码中专门配置一个方法用于管理所有依赖配置

    class IocConfiguration {
      configDependencies(
          {AnalysisService analysisService}) {
        var loader = GetIt.I;
    
        loader
            .registerLazySingleton<LoggingService((() =SimpleLoggingService()));
    
        if (analysisService != null) {
          loader.registerLazySingleton<AnalysisService((() =analysisService));
        } else {
          loader.registerLazySingleton<AnalysisService(
              (() 
  • Flutter快速构建设置界面

    Flutter快速构建设置界面

    设置(settings)一般是指用于配置App相关内容,看图比较直观

    对于设置界面的子项目来说一般有几种常见的类型

    • 输入类型(如展示的用户名)
    • 勾选类型(如是否允许后台推送)
    • 滑动设置(如音量大小)
    • 选项(如缓冲策略等)

    shared_preferences_settings提供了常用的选项和UI,同时设置结果持久化在shared_prefrences中,可以快速构建设置页面。

    在依赖中加入

    shared_preferences_settings:
        git:
          url: https://github.com/BarthaBRW/shared_preferences_settings.git
          ref: 9857951c728bd23df27995ef92da4e489a072f8c
      shared_preferences: ^0.5.6

    这里有个比较坑的地方就是shared_preferences_settings目前只在pub.dev发布了一个旧版本,旧版本依赖的shared_preferences比较老,对于AndroidX支持有问题,所以只有直接用依赖git的方式加入依赖,这里指定ref防止一些不稳定问题。

    使用方式比较简单

    import 'package:fish_redux/fish_redux.dart';
    import 'package:flutter/material.dart';
    import 'package:kiwi/domain/constant/settings_key.dart';
    import 'package:kiwi/domain/enum/js_engine_type.dart';
    import 'package:shared_preferences_settings/shared_preferences_settings.dart';
    
    import 'state.dart';
    
    Widget buildView(
        SettingsState state, Dispatch dispatch, ViewService viewService) 
  • 使用Github Action自动merge pull request

    Github提供了pull request功能,有时候在小团队开发或者个人仓库的时候,基于git分支策略,可能依然需要在feature分支开发,但是需要经常合并到master。

    这种情况下更偏好于PR能够自动merge,而不是等CI等自动检查通过后再点击merge按钮。

    Github Action可以在创建pull request的时候触发,从而自动完成这个过程。相关配置如下:

    name: Automerge
    on:
      pull_request:
        types:
          - labeled
          - unlabeled
          - synchronize
          - opened
          - edited
          - ready_for_review
          - reopened
          - unlocked
      pull_request_review:
        types:
          - submitted
      status: {}
    jobs:
      automerge:
        runs-on: ubuntu-latest
        steps:
          - name: 
  • Flutter打包后闪退问题

    最近在搞Flutter,在模拟器调试一切正常,但是flutter build apk以后真机闪退,看了下日志,报错如下:

    E/flutter ( 5319): [ERROR:flutter/shell/platform/android/platform_view_android_jni.cc(39)] java.lang.NoClassDefFoundError: g.a.b.o3
    E/flutter ( 5319): 	at g.a.b.r.v(Unknown Source:0)
    E/flutter ( 5319): 	at com.huangyunkun.kiwi.a.a(Unknown Source:102)
    E/flutter ( 5319): 	at com.huangyunkun.kiwi.MainActivity$a.a(Unknown Source:153)
    E/flutter ( 5319): 	at c.a.c.a.j$a.a(Unknown Source:17)
    E/flutter ( 5319): 	at io.flutter.embedding.engine.e.b.a(Unknown Source:57)
    E/flutter 
  • 使用Github Action发布函数到阿里云serverless平台

    使用Github Action发布函数到阿里云serverless平台

    本文首发于:https://developer.aliyun.com/article/741408 修改后发于本博客

    阿里云提供了函数计算,即serverless支持。同时阿里云还提供了fun cli命令行工具方便项目验证、发布等。发布函数虽然只是一句命令行的事情,但是做到集成发布平台还是需要准备对应的环境,配置和工具的。

    travis-ci可以用shell脚本完成,但是要求nodejs环境。在从travis-ci切换到Github Action的时候还需要重新写shell脚本,但是Github Action支持Dockerfile模式,可以使用更简单的方式来实现,同时更有利于复用。

    Github Action支持自定义,主要有两个方法,第一种是javascript路线(nodejs环境),第二种是dockerfile路线,支持直接run docker镜像。第二种使用覆盖面更广和容易,特别是我对nodejs的调试一直比较困难。

    我们要构建的这个Github Action思路很简单,提供一个node环境,预安装fun的稳定版本,然后直接运行fun deploy就行了。所有需要的参数要么通过ENV传递,要么通过input传递。

    自定义Github Action

    自定义的几个主要步骤如下:

    • 创建action.yml文件
    • 创建Dockerfile和必要的其他文件,比如entrypoint.sh
    • 创建README (发布到marketplace必要)

    首先创建一个action.yml文件,这个文件的内容会展示到github action marketplace中。

    示例如下:

    name: "Aliyun Serverless Action"
    description: "GitHub Actions for Aliyun Serverless 🚀 Deploy function automatically."
    author: 
  • 阿里云智能视觉AI开放平台

    阿里云推出了智能视觉AI开放平台,对于云服务商提供的这一块应用蛮感兴趣的。

    因为如果遇到了类似图片识别等需求,虽然有很多开源库,也有很多教程快速入门,但是实际上手很清楚,这种东西自己半吊子的搞识别率低,出了问题也不会改进。

    阿里云推出的智能视觉AI开放平台目前在公测环节,价格未知,目前提供三个方面的功能

    • 车型识别
    • 动植物识别
    • 商品识别

    直接进入https://visionai.console.aliyun.com/overview申请开通对应服务即可,目前只要实名即可开通

    首先看下车型识别,随便从网上下载了几张

    byte[] fileContent = FileUtils.readFileToByteArray(new File("k3-1.jpg"));
            String encodedString = Base64.getEncoder().encodeToString(fileContent);
    
    
            DefaultProfile profile = DefaultProfile
                    .getProfile("cn-beijing", "lxjVzJS3", "AqUFTsWDjqkPKC");
            IAcsClient client = new DefaultAcsClient(profile);
            RecognizeVehicleRequest request = new RecognizeVehicleRequest();
            request.setImageContent(encodedString);
    
            try {
                RecognizeVehicleResponse