微信接入调试方案

微信接入是个很头疼的东西,主要原因是 webhook 的 url 必须是服务器地址,无法在开发机上调试。
目前为止我用的方案是在服务器上抓包在本地模拟,配合单元测试把功能开发完成后,再放到服务器上调试,但调试过程中难免要对代码做修改,体验很不好。
最近受不了这么折腾,脑洞大开地想把服务器上的请求直接 proxy 到本地,然后发现 ssh 自带了这个功能。

主要的东西就是 ssh 的 -R 参数,这里假设微信后台填的 webhook URL 是 http://wechat.lazybee.me,本地开发环境开的端口是 http://127.0.0.1:8000,整个转发流程是这个样子的 Read more »

让 MacBook Pro 支持带鱼屏

最近入手 AOC LV343HUPX,3440 * 1440 的带鱼屏。万万没想到,14 年的 mac mini 和 12 年末的 macbook pro(13′ non-retina) 不支持这么大的分辨率,30Hz 的刷新频率,花屏现象很严重。
尝试过的方案有 SwitchResxDisableMonitor 等,用这种改分辨率的软件强开 3/4 的 2580 * 1280 还是可以用的,但字会比较糊,达不到理想效果,架不住喜欢作死,重置了多次 NVRAM 后,终于折腾出了成功方案。

总体方案是参照 这篇文章,有两个需要下载的东西,也把链接引过来。
首先是 AppleIntelFramebufferCapri.kext,这个 kext 是 osx 中管理 intel 驱动的组件,
然后是 KextBeast,这个是用来安装 .kext 文件的,不喜欢用的话也可以 Cmd + R 进恢复模式开 terminal 手动复制,位置是 /Volums/Macintosh\ HD/System/Library/Extensions。 Read more »

Lua5.1源码分析——Table

数据结构

Table 的定义在 lobject.h 中。

/*
** Tables
*/

typedef union TKey {
  struct {
    TValuefields;
    struct Node *next;  /* for chaining */
  } nk;
  TValue tvk;
} TKey;

//hash部分的节点
typedef struct Node {
  TValue i_val;
  TKey i_key;
} Node;


typedef struct Table {
  CommonHeader;
  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */ 
  lu_byte lsizenode;  /* log2 of size of `node' array */
  struct Table *metatable;
  TValue *array;  /* array part */
  Node *node;  //hash part
  Node *lastfree;  /* any free position is before this position */
  GCObject *gclist;
  int sizearray;  /* size of `array' array */
} Table;

Table中的数据存储分为两部分,数组部分array和hash部分node。数组部分就是一个TValue的C数组,而hash部分则是一个hash表,每个节点Node包括一组键值对,Table中的node变量记录hash表头。注意Node中的Key部分比较奇怪,这是一个union,里面可能放着一个TValue,也可能是一个TValue+Node,如果有TKey  a, 那么a.tvk.value == a.nk.value;  a.tvk.tt == a.nk.tt.不太明白为什么不直接用一个struct里面放TValue和Node,而要用一个union。
Read more »

Lua5.1源码分析——String

lua中的所有对象数据都用一个union Value来表示

/*
** Union of all Lua values
*/
typedef union {
  GCObject *gc;    //所有的GC对象
  void *p;                  // light userdata
  lua_Number n;    //lua_Number实际就是double
  int b;                      //布尔值
} Value;

由这个结构可以看出,除了lightuserdata, number, boolean外,其它对象都是gc管理的对象。GCObject也是一个union,包含了lua中的其它对象类型。 Read more »

网络寻址过程

假设一台设备ip地址为172.27.35.8,子网掩码为255.255.0.0,默认网关为172.27.35.1,要连接的地址为172.27.35.18。
首先ip地址与子网掩码做与操作,如果结果与网络上的另一台设备相同,则认为两台设备处于同一网段,该例中所有172.27.*.*的机器都在同一网段。172.27.35.8这台设备会向连通的所有节点发送广播询问是否有172.27.35.18,如果有这台设备,该设备就会进行回应,这样两台设备就可以连通了。如果找不到该地址的设备,就会连接到默认网关172.27.35.1,默认网关也有一个子网掩码,假设为255.0.0.0,作为网关的设备会继续向172.*.*.*的节点发送广播,寻找172.27.35.18,这样递归下去。
路由表是一个配置,里面可以设置ip和掩码还有对应的网关,这样在连接不同的地址时可以去不同的网关寻找,这样可以同时连通多个网络。

sqlalchemy 示例

正文开始前,不得不吐糟一下 ORM。

在很久很久之前,我是一个坚定的 ORM 黑,基于对数据库优化有点小研究,感觉这东西就是脱了裤子放 P,在带来性能下降的同时,带来的很多很重包依赖,项目中也在使用基本类似 SQL 语句的方案读写数据库。合作的人多了起来,直到有一天,我发现程序变成了这个样子:

class User(object):
    def get_by_id(self, id):
        ...
    def get_by_email(self, email):
        ...
    def get_all(self):
        ...

这个例子有点夸张,但总结一下,就是没有固定的标准,合作起来就容易错乱。

然后我要做的当然是整理下代码结构,不要这么乱来,结果越整理,发现越像 ORM,所以还是直接用 ORM 算了~


好了,正文开始。

几乎所有的例子都是从这个开始的:

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    email = Column(String)
    password = Column(String)

但我觉得这种定义对我毫无意义:

首先,我的数据库是多个项目都需要读写的,我有一个单独的 alembic 项目负责维护数据库的变动,我没有理由要在其它项目需要的字段发生变动时,跑到这个项目里修改代码;

其次,这些值的类型在 alembic 里都定义过,数据库里都是可以取到的,我没有理由需要重新定义一遍,我应该只需要定义 alembic 里没有的,需要用到的外键。

在问过几个练过 sqlalchemy 的朋友之后,得到的结论是:我太懒了,写几个不会死人,要为懒付出代价。 = ____ =

很喜欢 Ruby 里的 Active Record ,它几乎是一个完美的框架,sqlalchemy 倒是有一个叫 Elixir (这货不是 Erlang VM 上的语言,只是同名而已。。。)的扩展,跟 Active Record 很像,但最近更新时间是三年之前。 Read more »

三个 Elixir 小工具

学 Elixir 也有一段时间了,DSL 各种顺手,最近把代码整理了一下,一口气撸了三个 Elixir 的小项目:

Lazymaru (https://github.com/falood/lazymaru)

对 ruby 的 rest 框架 grape 的语法各种喜欢,于是用 Elixir 基于 cowboy 实现了一套,目前只实现了基本的 url route 功能。

MyDSL (https://github.com/falood/mydsl)

只一个 MySQL 的 DSL,绝非 ORM。都是按我自己习惯写的,不知道是否通用,有待改进。

ExJieba (https://github.com/falood/exjieba)

Jieba 分词的 Elixir 版,其实只是用 NIF 对 libcppjieba 做了一层封装,十分感谢作者特意把 libcppjieba 从 cppjieba 中分离出来。

CEGUI 0.8.3 编译

一.下载CEGUI源码和依赖库 http://sourceforge.net/projects/crayzedsgui/files/CEGUI%20Mk-2%20Dependencies/0.8.x/cegui-deps-0.8.x-src.zip/download

二.依赖库解压到文件夹 E:/DEP

三.打开CMake GUI, 在where is source code 里选择 E:/DEP文件夹, 在where to build the binaries 里选择  E:/DEP/project, 点击下面的configure,选择对应的 VS 版本, Configure之后点 Generate, 然后在E:/DEP/project 文件夹里就会生成对应的 VS 工程文件, 打开 CEGUI-DEP.sln , 分别将Debug和Release编译好. 中间可能会碰到外文导致的编译错误,将导致错误的字符串删掉就可以通过编译.

四.将 CEGUI 源码包解压到 E:/Cegui, 将 E:/DEP/project/dependencies文件夹考到 E:/Cegui 下, 用CMake GUI 生成VS工程文件,步骤同三中的,source和binaries路径都选择 E:/Cegui. 可能有几个warning,不用理.生成工程后就可以打开 sln 工程编译 cegui demo了. 如果 Cmake失败了,一定要把生成的文件都删掉重新再来一次,不然生成的工程会有错误

Git常用命令备忘

git init  初始化当前文件夹作为版本控制的文件夹,在当前文件夹里生成.git

git status   显示当前状态

git add “a.txt”   将文件”a.txt”添加到提交列表里

git reset “b.txt” 将文件”b.txt”从提交列表里移除

git commit -m “Add a.txt”  将提交列表里的文件进行提交,生成新版本

git log  显示各个版本的commit信息

git diff  HEAD 显示当前更改和最后一次commit的区别

git diff  –staged  显示add过的更改

git diff  显示还没add的更改

git checkout — a.txt   将该文件返回到上次提交的版本

git branch newbr  新建分支newbr

git checkout newbr 将当前版本切换到newbr分支

git rm “a.txt”  将文件移除并add此更改

git checkout master 切换回master分支

git merge newbr   将当前分支和newbr分支合并

HEAD^ 表示HEAD的上一个版本

HEAD^^ 表示HEAD的上上个版本

项目经历

魔塔:

 

魔塔

 

华囧道

华囧道

 

Prism

Prism2

Prism1

Prism3

 

吃货蛇

吃货蛇

 

泡泡堂

泡泡堂

 

仙剑五子棋

仙剑五子棋