类库大魔王/missdeer 2018-12-06T05:31:51+00:00 me@minidump.info 更换blog托管 2018-12-03T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/12/blog-hosting-switch 去年把blog托管到了coding pages上,以为可以为大陆提供更好的访问速度,但实际上效果似乎并没有想像的那么好,coding pages貌似是为了规避大陆网页要求备案,把大陆访问IP引导到了香港的主机上,网络一旦出了国,速度就会降很多,另一点是免费的coding pages要求在页面上添加他们的声明信息,虽然就算他们不要求,我也会在页脚处添加各种感谢声明,但强行要求就让我心里总有点疙瘩。

这两天偶然知道开源CDN服务jsDelivr可以直接加速github上的资源,比如我的blog仓库是https://github.com/missdeer/blog,使用gh-pagesbranch,那么如果有一个文件路径是/js/main.js,用jsDelivr则通过URLhttps://cdn.jsdelivr.net/gh/missdeer/blog@gh-pages/js/main.js访问,就可以获得CDN加速的效果,其中https://cdn.jsdelivr.net/是固定的域名,gh表示githubmissdeer/blog表示我的仓库,gh-pages表示所在branch,之后便是文件路径。

在中国大陆,jsDelivr是通过QUANTIL这家CDN(据说QUANTIL是网宿参股公司,QUANTIL国内节点为网宿实际运营)实现的,实测下来速度非常好,而且如果是js或css文件,可以通过添加.min自动获得紧缩版本,比如https://cdn.jsdelivr.net/gh/missdeer/blog@gh-pages/js/main.min.js,不用自己另外单独提供一份。

我把blog上几乎所有除了HTML外的静态资源,比如js,css,图片,字体文件等,全部替换成jsDelivr加速了。blog原本在coding pages上是用一个二级域名https://blog.minidump.info的,切换回github pages后不再用这二级域名了,而是顶级域名下加一级路径https://minidump.info/blog/,可以直接使用github pages的SSL证书。原来的二级域名就在linode上用nginx加了个301跳转到新地址。

最后,是修正leancloud上的评论记录,把原本在https://blog.minidump.info/上的评论全部转移到https://minidump.info/blog/上了。

所以现在时间可能主要花在blog域名的DNS解析(cloudflare家在大陆似乎并不好),301跳转,HTML文件下载这三部分了,其他上了CDN的静态资源应该比以前会快很多吧。

另外有一个问题,更新了blog,新增/修改的内容不能立即同步到https://cdn.jsdelivr.net/gh/missdeer/blog@gh-pages/这个路径下,要把gh-pages换成git commit的hash id,可能要过2天才会同步,这点略显繁琐。

]]>
imchenwen进度:优化 2018-12-01T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/12/imchenwen-WIP-optimization 这段时间主要是做了些优化。

终于找到了“关于”和“偏好设置”没有国际化的原因,需要装入qt_*.qm文件,比如简体中文则是qt_zh_CN.qm,在mac上运行macdeployqt并不会复制这些qm文件,Windows上的windeployqt则会复制一些其他语言的,但没有中文的。

Application menu

增加了“解析并播放视频”的菜单项,主要是想增加快捷键,并对用户明显,所以就加到主菜单去了。

play menu

在“快捷方式”菜单中增加了“在线电影”的分类,国内网上有很多在线看电影的网站,都是通过Flash播放在线视频资源,很多热门资源可以直接观看。

同时修改了视频地址嗅探操作方式,原本VIP类型的视频需要自己一个一个尝试使用解析网站获取视频地址,这样比较低效和麻烦,现在另外新开一个进程,单独嗅探某个URL下的视频地址,所以可以并发多个解析网站进行解析嗅探,另一个好处是也可以在后台嗅探在线电影网站的视频地址嗅探了。

另一个改动是把“快捷方式”的网站定义和VIP视频解析网站地址都写到网上了,每次程序启动从网上加载列表,所以列表可以自定义,这就很灵活了,特别是VIP视频解析网站可能变化很频繁,用户也可以自己维护一个列表。

shortcut menu

调整了“偏好设置”对话框,在顶部增加了一个图标工具栏。QDialog并不能在Qt Designer中直接拖拽增加一个工具栏,但可以通过代码增加,所以我的方法是在顶部放一个空的占位QWidget,然后在代码中用QToolBar替换掉,代码如下:

QToolBar* toolbar = new QToolBar(this);
layout()->replaceWidget(widgetPlaceholder, toolbar);
toolbar->setIconSize(QSize(48, 48));
toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);

效果如下:

configuration

]]>
MSVC与Go语言混合开发 2018-11-24T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/11/msvc-and-go 用C++写程序时,有些事情发现用Go做很容易,用C++则比较折腾,所以就想用Go实现,然后通过cgo链接到C++程序中。但是cgo在Windows上只能使用gcc实现,有时我又有必须使用MSVC的理由。

Go在Windows上可以直接用gcc生成静态库或动态库,但要让MSVC也能用上,需要做一些处理。

首先,生成静态库,比如:

set CGO_ENABLED=1
go build -buildmode=c-archive -o libgo.a main.go

然后,创建一个def文件,声明导出符号,比如libgo.def

EXPORTS
    Function1

接着,用gcc从该def和静态库生成一个dll:

gcc libgo.def libgo.a -shared -lwinmm -lWs2_32 -o libgo.dll -Wl,--out-implib,libgo.dll.a

这时,应该已经有了一个libgo.dll文件和一个libgo.def文件,用MSVC自带的lib程序生成MSVC可用的.lib文件:

lib /def:libgo.def /name:libgo.dll /out:godll.lib /MACHINE:X86

如果是64位环境,则将最后一个参数改为/MACHINE:X64

最后,修改Go编译器生成的libgo.h文件,将其中2行line #1开头的行删掉,2行_Complex相关的代码删掉。

这时,MSVC程序可以直接#include "libgo.h",代码中可以直接调用函数Function1,并在链接时添加对godll.lib的引用。

其实Go是可以直接生成dll文件的,但会把所有Go runtime的函数全部导出,略显冗余,所以我这里就通过自己创建的def文件来声明需要导出的函数。

]]>
imchenwen进度:内置播放器和DLNA投屏 2018-11-13T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/11/imchenwen-builtin-player-and-dlna 大约一年半前因为感觉遇到解决不了的技术问题,于是imchenwen的坑就扔下不管了。上个月的时候突然意识到,妹子喜欢看网卡的视频,优酷腾讯芒果爱奇艺等等,但是因为身体原因捧着个手机或iPad看会觉得头疼,看电视就要好很多,所以就萌生了在电视机上看网络视频的想法。

说干就干,首先在淘宝花了一百多块钱买了个“山寨”投屏器,折腾了一下发现可以把优酷腾讯爱奇艺这几个大厂的app投屏过去,但是芒果app的投屏功能就不稳定,B站app压根没有投屏功能,更别说其他杂七杂八的网站和视频源了。

于是翻出一年半前就停滞开发的imchenwen,经过三周的折腾,基本实现了内置播放器和DLNA投屏的功能。目前内置播放器功能比较完善,可以流畅观看绝大多数的视频包括电视直播,DLNA投屏倒是能投了,但是进度条要么不好拖,要么干脆不能拖,不过目前勉强够用了。

一些screenshots:

内置播放器

选项设置

电视直播

地址解析

大概说一下开发要点:

  1. 内置播放器是通过引入libmpv解决的,github上有libmpv官方的Qt使用的示例,非常简单易用,但是用老式的被deprecated的opengl-cb接口,新的render API用法官方示例是没有,但我通过看另一个项目MoonPlayer的用法,再自己连蒙带猜也试出来了,不直接用那代码的原因是imchenwen是基于QWidget的实现,MoonPlayer是基于QML的实现。后来发现另外有个Media Player Classic Qute Theater的项目,就是直接用QWidget+render API的实现的,看到得晚了。

  2. 无论是被deprecated的opengl-cb还是render API,视频输出都只能使用opengl-cb/opengl或libmpv,如果换成其他的,比如direct3d之类的,libmpv就会自己创建个窗口进行视频输出,所以不能用。网上倒是有OpenGL ES接口转DirectX或转Metal的库,可以试一下。

  3. 一年半前遇到的一个问题是如果视频被切成多段,用播放器播放会断一下,这个问题可以通过合成一个m3u8,给mpv设置一个prefetch-playlist的参数解决。

  4. mpv/libmpv对网络视频的支持比较好,提供了比其他播放器更多的参数,比如可以设置http的headers,可以单独设置referer,甚至可以设置cookie,更不用提http GET方法在URL后面加的query参数了。HLS流和RTSP流也能直接播放。

  5. DLNA投屏限制比较多,据我观察下来,它能支持的URL和文件格式就比较严格,比如URL后面query参数比较多的话,基本不能播放,文件格式m3u8似乎就不行,大概只支持最常见的mp4、flv、ts等。也不知道是因为我买的投屏器比较山寨,还是说业界都是这么搞的。

  6. 所以从网上弄来的视频地址有几种情况,要分别处理。最简单的一种情况是直接一个裸的诸如http://www.xxx.com/path/media.mp4这种URL,可以直接提交给投屏器播放。

  7. 如果是带query参数的,比如http://www.xxx.com/path/media.mp4?query1=value1&query2=value2&query3=value3,需要把URL转换一下,我的办法是在本地起一个http server,把本地的URL比如http://192.168.1.100:12345/path/media.mp4提交给投屏器,http server接收到GET请求时,程序自己启动一个http client去请求视频原始的URL,把收到的视频数据从http server转发给投屏器。

  8. 如果是一个m3u8,比如http://www.xxx.com/path.m3u8,则本地起一个http server,并提供一个投屏器支持的格式比如http://192.168.1.100:12345/path/media.ts,再程序自己去请求原始m3u8,解析出m3u8中视频的真实地址再继续请求回来视频数据,再转发给投屏器。

  9. m3u8本身也有几种情况,一种是里面就是一组视频真实地址,诸如http://www.xxx.com/path/media.flv?query1=value1&query2=valu2等等,这种就照第7步做。另一种是里面是相对路径,比如rpath/media.flv这种,要先拼出绝对路径的URL,再照第7步做。还有一种是里面是另一个m3u8的地址,可能是绝对路径,或能是相对路径,在得到绝对路径后再请求m3u8内容,直到最后得到视频真实地址,再照之前的做。

  10. 视频有可能是已经被分段的几个URL,需要自己拼成一个m3u8,再照第8步和第9步做。拼成m3u8时要加入#EXT-X-TARGETDURATION:#EXTINF:,后面的数字可以随意,只要前者的比后者的大就行,播放器在收到视频数据时能自动计算出视频的真实时长。

  11. 投屏器不像mpv有prefetch-playlist这样的参数,所以我现在的做法是把多段视频用FFmpeg合并成一段,全都只转封装成ts流,不转编码,那样就不会太耗时和耗CPU,我用2013Mid的MBA跑,也能即时转出来给投屏器用,基本不会卡,电视机分辨率不高的话,转个720p的就够了。

  12. FFmpeg转出来的ts流直接存到本地硬盘文件,http server再读硬盘文件转发给投屏器,经过试验,http header中不要带Content-Length,而且Content-Type必须是application/octet-stream,投屏器才会不断地接收http server喂给的数据,其他文件格式、Content-LengthContent-Type都可能会导致投屏器要么干脆没反应,要么有声音没图像,要么只有前面一段内容。

  13. 爱奇艺有视频有.265ts的格式,跟其他网站基本用H264的不同,用FFmpeg转封装要用不同命令。目前我分别用这两条目前转封装:

    ffmepg -y -protocol_whitelist "file,http,https,tcp,tls" -i http://127.0.0.1:12345/media.m3u8 -c:v libx265 -c:a aac -copy ts media.ts
    
    ffmepg -y -protocol_whitelist "file,http,https,tcp,tls" -i http://127.0.0.1:12345/media.m3u8 -c:v copy -c:a aac -copy ts media.ts
    

    FFmpeg了解不多,不知道有没有更好的办法。

  14. 现在的问题是:不支持HLS/RTSP投屏;没有手机端;mac上用QWebEngine太重了,用系统的WebView大概会好一些。

]]>
试用基于有赞云的个人网站在线收款解决方案 2018-08-07T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/08/try-youzan-pay 老早就注册有赞云了,之前随便玩了一下,感觉可以用,加上自己对web开发并不了解,就放下了。

今天突然心血来潮,用Go折腾了一下,用于demo是很简单的,有赞的文档也还不错,虽然并不了解web开发,但拿别人的代码过来改改问题不大。

主要的工作流程为:

  1. 从web上获取相关信息,比如价格、客户资料等,创建收款二维码
  2. 有赞云返回二维码的id、url及base64编码后的图像信息,程序记录二维码id及用户信息的对应关系,后面有用
  3. web页用js通过websocket获取二维码url或base64编码后的图像信息,并显示
  4. 用户使用微信或支付宝扫一扫二维码进行支付
  5. 扫完二维码后会跳转到有赞的一个页面,点击该页面上的支付按钮,有赞会推送消息到后台设置的回调地址上,状态是WAIT_BUYER_PAY
  6. 用户支付完成后,有赞会再次推送消息,状态是TRADE_SUCCESS
  7. 有赞推送的消息中只包含订单号,程序要通过订单号反查对应的二维码id,再查到用户信息完成一次交易

这个方案的优点是无需公司资质,无需接入支付宝和微信,可使用支付宝和微信扫码支付,支持储蓄卡和信用卡。

缺点是只能在网站上使用,在手机上不能唤起支付宝和微信app。另外据说有赞的风控比较严格,动不动就被冻结资金不能提现,需要找客服解冻。

程序代码在这里,代码很乱,仅供演示。在线demo在这里,可以输入小额金额进行支付体验。

]]>
tinc后续 2018-07-26T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/07/tinc-follow-up 之前用tinc构建了虚拟专网,实现了在不同局域网内的机器通过tinc互相访问,但是遇到一个问题,我想从公司里访问到家里其他没有装tinc的机器,或者从家里其他没有装tinc的机器访问到公司里装了tinc的机器。经过一番简单的设置便可以达到想要的效果。

家里一台HTPC装了tinc,新增IP为192.168.88.3,内网IP为192.168.66.110,家里所有机器网关都指向软路由,假设IP为192.168.66.1,修改相应配置。

修改所有机器上的/etc/tinc/bignet/hosts/shhtpc文件,头部增加一行:

Subnet = 192.168.66.0/24

刷新tinc的配置,要用sudo

sudo tincd -n bignet -kHUP

设置流量转发,修改/etc/sysctl.conf

net.ipv4.ip_forward=1

执行以下命令使其生效:

sudo sysctl -p

修改路由器192.68.66.1上的静态路由:

sudo ip route add 192.168.88.0/24 via 192.168.66.110

至此,家里所有机器的流量先全部流到路由器,路由器发现目标IP地址是192.168.88.0/24范围内的,重路由到HTPC上(192.168.66.110)。

修改公司所有机器上的/etc/tinc/bignet/tinc-up文件,增加一条静态路由:

sudo route add -net 192.168.66.0/24 192.168.88.3 255.255.255.0

即把192.168.66.0/24网段的流量路由到HTPC上。

因为我家里的路由器和HTPC使用的操作系统都是Linux,公司的电脑都是macOS系统,所以增加静态路由使用不同的命令。

至此,公司可以直接访问192.168.66.0/24网段内的所有机器。


tinc装在Windows上只需要装好tap-Windows驱动,设置好虚拟IP和子网掩码,就不需要手动设置路由,但在上面这种情况下,需要另外加一条静态路由,以管理员身份运行cmd.exe,输入命令:

route add 192.168.66.0 mask 255.255.255.0 192.168.88.6 metric 3

命令中192.168.88.6是本机的tinc虚拟IP,我猜改成HTPC的IP应该也可以,没试过。


由于不能控制公司的路由器,所以不能给公司所有主机修改路由设置,如果要从家里访问公司里其他主机,比如访问公司内网的网站,我认为比较简单的方法是修改家中的路由器设置:

  1. 开一个SSH隧道到公司任意一台装了tinc也装了OpenSSH server的机器:

    ssh -D 8089 -f -C -q -N username@192.168.88.4
    

    其中192.168.88.4就是公司某一台装了tinc也装了OpenSSH server的机器。

  2. 装redsocks,并指向SSH隧道开的本地端口:

    ip = 127.0.0.1;
    port = 8089;
    type = socks5;
    

    假设redsocks监听在58096端口上。

  3. 修改iptables防火墙设置:

    -A SS -d 10.0.0.0/8 -p tcp -j REDIRECT --to-ports 58096
    -A SS -d 173.36.0.0/14 -p tcp -j REDIRECT --to-ports 58096
    -A SS -d 172.0.0.0/8 -p tcp -j REDIRECT --to-ports 58096
    -A SS -d 171.68.0.0/14 -p tcp -j REDIRECT --to-ports 58096
    -A SS -d 72.163.0.0/16 -p tcp -j REDIRECT --to-ports 58096
    

    把所有公司内网用到的IP段流量都重定向到58096端口。

  4. 在公司某一台装了tinc的机器上装一个DNS server,在家里把所有公司内网用到的域名都使用该DNS server进行解析,比如dnsmasq设置为:

    server=/.cisco.com/192.168.88.4#35353
    server=/.webex.com/192.168.88.4#35353
    server=/.webexconnect.com/192.168.88.4#35353
    server=/.wbx2.com/192.168.88.4#35353
    

    其中192.168.88.4就是公司某一台装了DNS server的机器,监听在35353端口。

这时,家里所有机器应该都可以访问公司内网的网站,登录收发邮件等等。

我之前并没有使用SSH隧道,而是在公司机器上使用polipo提供http代理,发现它并不能正确代理非http端口的流量请求,而SSH隧道就没这个问题,不知是polipo的限制,还是因为SSH隧道使用socks5协议是会话层协议的缘故。

]]>
使用tinc构建虚拟专网 2018-07-16T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/07/tinc-virtual-private-network 之前写过一篇文章讲如何在家里无缝访问公司网络,用的是frp的方案,但正如使用ngork一样,frp也会莫名其妙地突然不工作,而且几乎没有什么错误信息可供调查。后来知道了有zerotier这个东西,相对来说还是比较稳定的,速度也凑合,免费额度可以在一个网络中添加最多100个设备,但是流量通过别人的服务器总归有点不爽,直到最近知道了tinc这个东西,可用于创建点对点的虚拟专网。

经过近一天的折腾,终于把公司两台iMac,家里一台Linux HTPC,以及Linode东京1一台VPS用tinc连起来了。tinc的安装配置使用都非常简单,只不过网上的资料比较零散,有一些还是错的,其实只要看linode的一篇文章以及tinc的官方文档,基本能解决所有tinc相关问题。

tinc的工作方式依赖于tuntap,现在的Linux发行版基本上都已经带了tuntap驱动,所以直接从官方仓库使用相应的命令安装tinc就能工作。在macOS上则需要自己安装一个tuntaposx驱动,可以通过brew cask install tuntap进行安装,也可以自己从网上下载安装包手动安装,甚至可能直接安装一个tunnelblick都会自动装一个驱动。可以用命令行kextstat |grep -e tun -e tap 看一下是否已经安装成功,如果没有任何输出,则需要自己安装,如果用brew cask或手动安装失败报错,则看一下/Library/Extensions目录是否有tap.kexttun.kext两个目录,如果有,则通过以下命令装载:

sudo kextload /LibraryExtensions/tap.kext
sudo kextload /LibraryExtensions/tun.kext

这时再用kextstat |grep -e tun -e tap看,估计就有输出了,如果还是没有,则到System Preferences-Security & Privacy看看是否被禁止了,若是被禁止了,就强行同意即可。

安装好了tuntap和tinc,就可以开始配置,Linux和macOS下基本是一样的,创建一个目录:

sudo mkdir -p /etc/tinc/netname/hosts

其中netname是自己随意设定的网络名,一旦设定,所有节点都要使用相同名字,之后在tinc的命令行中也要用到。

/etc/tinc/netname目录下创建tinc.conftinc-up/tinc-down,可以参考linode的文章编写。其中所有节点中必须要至少有一个节点是有公网IP(所有其他节点都能访问到)的,其他节点就都连这个节点进行中转,照tinc的理念,其他节点一旦通过中转建立好连接后,会视情况进行点对点直连或仍然继续通过节点中转。可以有多个节点拥有公网IP并进行中转,其他节点也可以配置连接多个中转节点。

tinc-up/tinc-down在Linux下和macOS下的命令也许略有不同,比如我的tinc-up在Linux下是这样的:

#!/bin/sh
ip link set $INTERFACE up
ip addr add 192.168.88.3 dev $INTERFACE
ip route add 192.168.88.0/24 dev $INTERFACE

在macOS下则是这样的:

#!/bin/sh
ifconfig $INTERFACE 192.168.88.5 192.168.88.2 mtu 1500 netmask 255.255.255.0
route add -net 192.168.88.5 192.168.88.2 255.255.255.0

同样tinc-down也要使用平台相应的命令。

然后在/etc/tinc/netname/hosts目录下,创建一个与tinc.conf文件中Name项的值相同的名字的文件,比如Name = node1,则创建文件名为node1node1的内容主要大概是这样:

Address=my.xxx.com   # 公网地址,可以是域名或IP,如果不是中转节点,可以不要这一行
Subnet=192.168.88.2  # 内网地址,可以是一个网段或一个具体IP

再之后,通过命令生成密钥:

sudo tincd -n netname -K4096  

这个命令会生成一个RSA公钥和一个私钥,会询问密钥保存的文件路径,其中要公钥需要添加到hosts文件的末尾,可以直接指定hosts文件路径作为公钥文件路径。

最后,把所有节点上的hosts文件都互相交换,存放一个副本到所有其他节点的/etc/tinc/netname/hosts目录下,就可以运行tinc daemon命令了:

sudo tincd -n netname -D -d 3

第一次运行,可以先加-D参数,让进程放在前台运行,加-d 3打印详细的调试日志以供出问题时查看,要杀掉该进程,不推荐直接使用kill命令,而是提供了相应的方法:

sudo tincd -n netname -k

这时可以通过ifconfig命令查看是否多了一个名字为netname的网络连接,IP则是在tinc-up设置的。还可以互相ping一下对方IP,没什么问题的话,几个机器应该可以当成在同一个网络里互相访问了,可以把-D-d 3参数去掉:

sudo tincd -n netname

还是比较简单的,唯一比较麻烦的是新加一个节点的话,要在所有节点都同步添加一个hosts文件,如果修改了配置,要用命令更新:

sudo tincd -n netname -kHUP

用tinc替换了zerotier体验了一下,感觉不错,要是有个GUI的配置工具以及hosts目录同步功能,就完美了!

]]>
Clang on Windows for Qt 2018-07-10T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/07/clang-on-windows-for-qt 几年前也曾经试图折腾过Clang on Windows,那时候的完成度还不高,只能配合MinGW使用,而且头文件搜索路径还是源代码中硬编码的。

现在完成度已经很高了,Chrome for Windows已经转而使用Clang编译。Clang官方支持2个target,分别配合MinGW和MSVC使用,只要在设置好PATH和target,clang就能自动使用对应的头文件,库文件,链接器等等。

偶然发现Qt 5.11.0已经带了win32-clang-msvc这个mkspec,而5.11.1增加了win32-clang-g++,这意味着在Windows上已经可以使用clang编译Qt程序,并且随意切换target。

Qt官方提供msvc2015和msvc2017编译后的二进制文件下载,可以直接使用从LLVM官网下载的Windows installer,甚至已经在LLVM 7.0的snapshot可以使用。可以编写一个批处理文件来设置环境变量:

set VS140COMNTOOLS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\"
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
set PATH=%PATH%;"C:\Tools\LLVM-7.0.0-r336178-win64\bin\";C:\Qt\Tools\QtCreator\bin\;C:\Qt\5.11.1\msvc2015_64\bin\

之后每次只要先执行这个批处理文件,然后执行命令:

qmake -r -spec win32-clang-msvc src.pro
nmake 或 jom

就可以使用clang编译Qt程序了,最终链接的是msvc版本的Qt库。

至于使用MinGW的target,我现在使用msys2的版本。msys2提供编译好的MinGW-w64套件,有提供32位和64位两个版本。Qt也有现成的编译好的文件,分别有32位和64位,静态链接和动态链接共4个版本,有时候静态链接的版本会迟一点发布。使用pacman安装:

pacman -S mingw-w64-i686-qt5 mingw-w64-i686-qt5-static mingw-w64-i686-clang
pacman -S mingw-w64-x86_64-qt5 mingw-w64-x86_64-qt5-static mingw-w64-x86_64-clang

这会下载几GB的东西,安装后可能会占用几十GB的空间。之后如此使用:

PATH=/mingw64/bin:$PATH /mingw64/bin/qmake -r -spec win32-clang-g++ src.pro
PATH=/mingw64/bin:$PATH /mingw64/bin/mingw32-make

至于Qt程序本身,并不会怎么受clang影响,除了可能会要求更规范一点?多数问题然后是MSVC和MinGW套件的区别的问题,在.pro文件中,则使用win32-*g++*win32-*msvc*来区分两种套件即可。

]]>
在家里无缝访问公司网络 2018-04-27T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/04/access-internal-network-seamless 有时候在家里时想访问公司网络,干点活(真是个好员工),主要就是开开内网的网页,连连内网的IM(Cisco Jabber)。本来这个事情只要有一个VPN就可以搞定了,但是!但是我没有权限申请VPN,于是只好另辟蹊径了。

首先,找到一个用于搭建内网隧道的反向代理工具frp,通过它在家里开一个服务端,在公司开客户端,于是家里的机器上就有了一个socks5端口,通过该端口就可访问到公司内网的资源了。于是网络拓扑大体如下图所示:

https://www.umlgen.com/svg/UDfpA2v9B2efpStXvIhEpimhI2nAp5N8ICnBAI_AB2b9pLCeAIfDvULApialJL58piyjICohLAZcvL80Whpyb5I5yioybFpoOeLeY1W8kAJcv3pjt_1qJ_-pERjUB6uDXoWnD80eYKNIdPcRc8oiDTCtCHckgfQN2sPpHdvkAegrHVcb9Qb5o5gT4lE0K24WKo7YwQAPBxQlVpvb8wQ57Y41piYwdlOkUBwlhyB2xEc6_YSxTWCTZAd7CG1PHv2PiO51cP52kAUR9wPQbzIopEHKGnGhm47nVChM5oqJSMamGjRmVCsK5-isF9kp1hyUOnHBTcv-DdS_VWr-A1ecj3pVkFjPPpUoby4X3ejHNLqxQ33pSe7Z2La06lww6WQQkk10HHDo3E3b0eORX0CD50mH8mmHOmmHFrukXzIy560A1G0bkixu

我把服务端放在占美x86小主机上,Banana Pi只负责拨号、路由和X墙

有了隧道,我之前是写了一个pac文件,把公司常用的几个顶级域名全部走代理,浏览器之类能支持pac文件的程序就能工作了,但程序如果不支持pac文件就歇菜了。要实现无缝访问,还需要做几件事。

  • DNS解析。内网资源的域名只有内网的DNS服务能解析,这也可以通过frp解决,在占美x86小主机上开一个非标准端口,比如6001,加上之前说的反向代理,frp客户端侧的配置文件如下:
[common]
server_addr = ip.address.at.home
server_port = 7000

[http_proxy_on_windows]
type = tcp
remote_port = 6001
plugin = http_proxy
use_encryption = true
use_compression = true

[socks5_proxy_on_windows]
type = tcp
remote_port = 6002
plugin = socks5
use_encryption = true
use_compression = true

[dns_proxy_on_windows1]
type = udp
remote_port = 6001
local_ip = dns.server.ip1.at.company
local_port = 53

[dns_proxy_on_windows2]
type = udp
remote_port = 6002
local_ip = dns.server.ip2.at.company
local_port = 53
  • 再通过dnsmasq把那几个内网域名指向该非标准端口就可以了,其他默认的不变:
server=208.67.222.222#5353
server=/.domain1.com/127.0.0.1#6001
server=/.domain2.com/127.0.0.1#6001
server=/.domain3.com/127.0.0.1#6001
server=/.domain4.com/127.0.0.1#6001
server=/.domain5.com/127.0.0.1#6001
server=/.domain6.com/127.0.0.1#6001
  • 分流。本来已经在Banana Pi强制所有海外IP走代理,现在只要把内网资源的IP分流到占美主机上的socks5端口即可。在Banana Pi上编译一个redsocks,redsocks可以把流量导到socks5端口。再修改一下iptables设置:
-A SS -d 127.0.0.0/8 -j RETURN
-A SS -d 192.168.0.0/16 -j RETURN
-A SS -d 169.254.0.0/16 -j RETURN
-A SS -d 224.0.0.0/4 -j RETURN
-A SS -d 240.0.0.0/4 -j RETURN
-A SS -p tcp -d 10.0.0.0/8 -j REDIRECT --to-ports 58096
-A SS -p tcp -d 173.36.0.0/14 -j REDIRECT --to-ports 58096
-A SS -p tcp -d 172.0.0.0/8 -j REDIRECT --to-ports 58096
-A SS -p tcp -d 171.70.124.0/14 -j REDIRECT --to-ports 58096
-A SS -p tcp -d 72.163.0.0/16 -j REDIRECT --to-ports 58096
-A SS -p tcp -j REDIRECT --to-ports 58097

其中58096是redsocks开的端口,58097是统一海外代理。

这些步骤之后,所有从R6300v2走的设备都能享受到正确的DNS解析和TCP分流,不需要pac文件,浏览器、IM都能正常访问到内网资源。

]]>
UMLGen开发踩坑 2018-03-31T00:00:00+00:00 类库大魔王/missdeer https://minidump.info/blog//2018/03/umlgen-develop-memoir 最近这段时间都在写一个叫UMLGen的GUI程序,从名字可以看出,就是一个用来画UML图的工具,与大多数现有的WYSIWYG(所见即所得)的UML画图工具(比如Visio,StarUML等等)不同的是,UMLGen使用代码的形式来描述UML图的呈现,与LaTeX的思想类似,即WYTIWYG(What You Think Is What You Get,所想即所得),我个人认为这种方式特别适合程序员使用。现在可用性已经很好了,主窗口截图如下:

UMLGen main window

程序是用Qt写的,开发过程中还是遇到一些坑,记录一下。

  • QtSvg模块实现的SVG标准有限,不能支持某些SVG,比如下面两张图,使用Firefox或Chrome浏览器查看,一切正常,用QtSvg则惨不忍睹。

math

math error

latex

latex error

除了换个支持完整的SVG库,就只能在这些时候不用SVG,改用PNG了。用PNG格式的问题是后端导出的PNG格式都是带白色背景的,而SVG是无背景透明的,这是我情愿尽量使用SVG格式的原因。

  • 用Scintilla编辑代码,自己写了一个简单的lexer,因为支持了多个后端,于是就有多种语法,所以在一个lexer里要同时支持多种语法,就会有坑,现在暂时也没想实现得多完美,这个留待以后版本改进。

  • Scintilla的Qt port对XPM图片格式支持有问题。XPM文件用文本编辑器打开可以看到是一个const char *[]的变量声明及初始化,但Scintilla的Qt port在register image时接收的参数被改成const char *,于是就对不齐了。

]]>