木是伊说 - 编程
type: channel
link: http://www.wiseclock.ca/category/code/
description: talk is cheap, show me the code.
items: 记录用docker搭建parse服务器
items: Java讀取文本文件的大坑
items: 那些年，開發Hybrid App遇到過的坑（React Native）
items: Webkit新特性Backdrop-filter試玩
items: Typecho的Prismjs插件
items: .Net環境下運行JavaScript淺談
items: 文字類遊戲引擎

记录用docker搭建parse服务器
type: item
date: 2021-10-05T08:35:00+00:00
description: 休假在家，时间比较充裕了。除了没日没夜地打一打哈利波特之外，还是干点事儿好了…… 国内一直因为众所周知的缘故不能使用Firebase的服务，导致我手游半成品也一直没有什么心思继续完善。而切换到Playfab又有其他问题（比如没办法很好地实现玩家交易板功能），索性自己捣鼓用Parse手撸服务器好了…… 环境需求 安装Parse需要有Node、MongoDB，虽然这俩我都已经有了，但各种版本号、用途不一的问题，让我觉得似乎直接拿来调戏Parse不是个明智之举……所以打算搞个Docker，在Docker里装Parse。反正现在Windows可以装Sub-Linux了，无缝衔接应该会很方便。 安装Docker 安装WSL2 因为这台电脑是年初才配的，装的Windows也够新，所以安装子Linux系统还是很方便的。只需要用管理员模式打开控制台，运行：wsl --install就可以了。默认会安装Ubuntu，不过反正我也挺喜欢Ubuntu的，就不改了。 下载好所需资源之后会提示你在重启WIndows之前不会有任何更改生效。重启之后Ubuntu便会自己蹦出来安装。 装好之后你需要给Ubuntu创建一个初始用户，输入用户名和密码即可。最后再运行一次sudo apt update && sudo apt upgrade就算是搞定了——可以直接在Windows里打开Terminal，在下三角里选择Ubuntu运行想在Linux下运行的命令（不过暂时用不到了）。 安装Docker 在装好WSL（目前默认版本号是2，所以是WSL2），就应该装Docker了。 嘛……实际上这也不是这篇文章的重点，装Docker感觉和装其他软件没啥区别。只要去Docker for Windows的下载页面下载下来安装即可……安装之前会有个小勾勾选上了WSL2，确保它是勾着的就好。 安装完成之后会需要登出/重新登入一次Windows，做好准备【。 安装Parse 安装MongoDB Parse支持NoSQL，也支持Relational Database（默认是MongoDB和Postgres）。但既然都用了这么方便的后端了，谁还用关系数据库啊！果断选择MongoDB。 在Docker上安装MongoDB也很方便，只要Docker for Windows是开着的，你就可以打开任何终端运行Docker的命令——我用的是Windows Terminal。 docker run --name rin-fishing-db -v /data/rin-fishing-mongo:/data -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin -p 27017:27017 -d mongo 输入以上命令，就会在Docker里新建一个叫rin-fishing-db的Container。名字随意，自己明白意思就行。这里用户名密码我都设置成admin了，反正本地开发，方便…… 顺带一提，数据储存位置在\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\。 安装Parse 安装好MongoDB，就可以装Parse本体了。运行： docker run --name rin-fishing-server -e PARSE_SERVER_APPLICATION_ID=rin-fishing -e PARSE_SERVER_MASTER_KEY=MASTER_KEY -e PARSE_SERVER_DATABASE_URI=mongodb://admin:admin@mongo/parse_server?authSource=admin --link rin-fishing-db:mongo -p 13579:1337 -d parseplatform/parse-server 相同地，设置的名字随意。Application ID和Master Key在开发环境也可以随意，产品上线的话就请自己掂量掂量了【。 [scode type="yellow"]这里还有个坑，就是设置端口的时候，因为我的1337端口被占用了，就用了13579。一开始我用的是-p 13579:13579也就是外部访问和内部都是13579，结果访问不到……所以如果各位要修改端口号，也请务必保留内部端口为1337不变。[/scode] Parse Dashboard 装完Parse，我们还可以装一个网页版的控制台： docker run --name rin-fishing-dashboard -e PARSE_DASHBOARD_APP_ID=rin-fi…

Java讀取文本文件的大坑
type: item
date: 2021-05-28T10:04:00+00:00
description: 今天才發現的大坑，大概是我玩Java太少了。 有個函數： BufferedReader reader = new BufferedReader(new FileReader(stopWords)); String line = reader.readLine(); while (line != null) { STOP_WORDS.add(Pattern.compile(line, Pattern.CASE_INSENSITIVE)); line = reader.readLine(); } reader.close(); 在IntelliJ IDEA測試環境下完全沒問題，可以順利載入所有文本。 但到了生產環境發現只有ASCII字符有效。 一開始還以為是UTF-8 BOM的問題，改成帶BOM的存了一次，還是不行。 後來才發現，原來FileReader並不會強制默認編碼到UTF-8。Java 11倒是可以手動設置new FileReader(fileName, StandardCharsets.UTF_8)，但Java 8就無緣了。 無奈，只好轉用Files.newBufferedReader，這個函數在Java 8默認使用UTF-8，但Java 7裡還是需要手動設置的。 所以最後改成了： BufferedReader reader = new BufferedReader(Files.newBufferedReader(Paths.get(path))); 運行……發現其他行都正常了，但首行還是不行。想到了之前添加的BOM…… 好嘛，到頭來還得把BOM刪回去…… 行吧。 EOF

那些年，開發Hybrid App遇到過的坑（React Native）
type: item
date: 2018-09-16T06:18:00+00:00
description: 這些年在開發App上也是遇到過不少坑了……從native到hybrid，從UI到authentication，遇到的坑是接連不斷，踩完一個掉另一個、從老坑爬到新坑一陣子才發現還是老坑好…… 現在基本沉澱好了，來總結一下，為以後失憶的自己以及正在辛苦挖掘的新入行的農民們留下點蛛絲馬跡。 為什麼選擇Hybrid App 一開始嘗試的時候也試圖開發native的iOS和Android App，不過很多東西來來回回改，兩邊都要顧及到，一個是開發時候耗時耗力，再就是維護成本也是雙倍的。像我這種懶人……自然更傾向於code once, run everywhere的Hybrid App了！ Hybrid App架構選擇 嘗試過幾種不同的Hybrid App架構，比如Xamarin、Ionic/PhoneGap (Cordova)以及React Native。最後認定的還是React Native——不得不說，真的是好用。 Ionic/PhoneGap 對於一些小型App來說其實Ionic/PhoneGap是一個很好的起點，因為你基本上只需要了解HTML和Javascript就能很好地上手了。 其中Ionic自帶的UI設計甚至會根據手機系統切換（保持和原生App一直的設計，比如說Android用的就是Material Design）。其自帶的豐富多彩的Components也能滿足大部分開發需求——比如按鈕、彈窗、ActionSheet等等。就算這些無法滿足你的App需求，你也還能使用Cordova Native插件來幫助開發——比如很受歡迎的一個就是AdMob，用來在App中插入廣告。 但如果你的項目比較複雜，或者需要展示的東西比較多（大型List），用Ionic/PhoneGap可能會嚴重拖慢App的性能。因為歸根結底Ionic/PhoneGap都是使用內嵌瀏覽器渲染的。雖然有辦法消除原生瀏覽器的300ms延遲，但面對龐大的UI渲染，Ionic/PhoneGap還是很吃力的。曾經我用Ionic做了幾十個卡片，每個卡片上有一些文本信息和一個內嵌的List，整個App滑動起來就已經不是特別順暢了。 Xamarin Xamarin和Ionic不同，完完全全是基於Native架構的。要說它是個Hybrid開發框架可能不太確切，但它確實是一個非常不錯的跨平台開發框架。和Ionic不一樣，Xamarin是直接和最新的SDK溝通，確保你能用到最新的API，然後把C#寫的代碼編譯成Native App。其實我挺愛Xamarin的。（讀到這裡你們應該能猜到後面會跟一個「但是」了……） 不過（我就不寫「但是」！），讓我棄了Xamarin這個坑的主要原因是它的用戶界面開發。誠然，Xamarin自帶的Xamarin.Forms能夠解決可能90%以上的需求——一次設計，跨平台分發。但同時你也需要注意到剩下10%的use cases會是極其痛苦的，因為一旦你有什麼UI上的需求在自帶庫中無法實現的話，你就需要手擼代碼實現。別理解錯，我說的手擼代碼是你真的需要對所有你想要分發到的平台做一個小插件。比如我當時的需求是在卡片裡內嵌一個可改變順序的List，我就需要在iOS和Android包裡分別寫一個Custom Renderer來實現——他們的代碼還很不一樣，因為底層SDK不同嘛。另外Xamarin的UI設計和Android也比較類似，用的是XAML，也有各種Layout，其實我個人覺得還是比較痛苦的。 最後就是Xamarin提供的插件真心不多——至少在我當時用的時候是吧，還有很多已經屬於比較過時的API了。考慮到需求裡可能會有蠻多沒有插件支持的功能，如果都要自己手擼可就太痛苦了，我還不如切回Native開發呢……所以最終放棄了可愛的Xamarin。 React Native React Native是我最後接觸到的Hybrid框架了。但是這東西一用就愛上了啊。相較於Ionic和Xamarin，React Native是真的取其精華、去其糟粕了。它擁有Ionic編寫UI的便捷，也擁有Xamarin執行的效率。 它不存在Ionic的性能問題，因為它本來就可以算是個半原生App了。React Native是一個用ES6編寫的框架，在你的App編譯後會將所有代碼打包成一大塊的js文件，然後React Native核心會用Objective-C或Java API將這個js文件渲染成Native View——感謝現代Javascript引擎，讓我們完全感覺不出用React Native開發的App和原生App的區別。 同時你也不需要為UI編寫擔心，因為React Native的UI編寫起來和HTML相差無幾。比如這個就是一個簡單的React Native頁面： import Rea…

Webkit新特性Backdrop-filter試玩
type: item
date: 2016-02-22T07:12:00+00:00
description: 昨天想要做個透過透明DIV對下層DIV使用滾動條的效果的時候無意間發現了一枚好東西，Webkit的新特性「Backdrop-filter」。它可以對任意在其下面（z-index）的圖層（包括動態圖片、視頻等）使用濾鏡特效（filter），而不像現在僅有背景濾鏡、圖片濾鏡以及顏色濾鏡而已。 不過因為這個特性還處於開發階段，默認只有使用Webkit Nightly Build的瀏覽器才可優先體驗。但其實它已經被多個版本的Webkit所包含了，詳情見：Can I Use。 iOS Safari 9.2及以上已經可以直接使用-webkit-backdrop-filter實現效果了——這也是解了我一惑，前段時間看到忘了是啥日報之類的網頁，底端居然像iOS dock一樣有毛玻璃效果，很是驚奇，現在想來肯定是-webkit-backdrop-filter沒跑了…… 普通版本的Chrome若想開啟這個功能，進入設置頁面將其啟用並重啟瀏覽器即可。（注：不支持-webkit-前綴，只有直接使用backdrop-filter時才能見到效果） 我也用它簡單地做了一個演示，玩了一會兒…… See the Pen GobQjR by Wise Clock (@WiseClock) on CodePen. 想了解詳情可以去官方說明博客或去官方演示頁面欣賞OwO

Typecho的Prismjs插件
type: item
date: 2015-11-30T04:15:00+00:00
description: 用了一段時間的Typecho了，感覺挺不錯，但有個問題就是代碼塊不會自動高亮。然後我就找了Syntax Highlighter for Typecho來用……畢竟老牌貨嘛，還是很不錯的，但對行內代碼高亮不支持，修改也不太方便……然後我就找來了HighlightJS…… 經過一番修改，把HighlightJS改成了只支持行內代碼高亮，然後配合著Syntax Highlighter高亮大段代碼一起用，效果還是很讚的。但我是強迫症啊！！！於是乎…… 我自己摸索著寫了個插件，高亮庫用的是Prism.js，也是個老牌高亮庫了。效果如下： 代碼段落 高亮語言：C# int startDate = 1; int startHour = 10; int startMin = 30; DateTime now = DateTime.Now; if (now.Day != startDate) return; while (now.Hour < startHour) { Console.WriteLine("長文本測試 test test test test test test test test test test test test test test test test test test test test test test test test"); Console.WriteLine("HOUR NOT YET"); Thread.Sleep(1000 * 60 * 5); now = DateTime.Now; } 行內代碼 高亮語言：JavaScript 這是一句話。var imgs = document.getElementsByTagName("img");這是第二句話。 用法 使用方法很簡單，只要在```或者`之後輸入相應的語言即可，例如： ```c# Console.Write("Hello World!"); ``` 或者行內代碼： `js console.log("Hi!");` 後台參數 後台可以修改的參數如下： GitHub Prismjs repo on GitHub. 下載 v1.0.7：Prismjs.1.0.7.zip 更新 v1.0.7：修復IE不支持element.remove()函數的問題，另外改了下coy主題，背景也會跟著滾動了 v1.0.6a：修復一個空行不計算高度的錯誤，感謝@jrotty指出 v1.0.6：去除JQuery依賴，修復強制換行模式下最後一行不被計算高度的問題 v1.0.5：強制換行模式下行號正常顯示 v1.0.4：後台添加使用說明、支持大小寫混用的語言名稱 v1.0.3：修正不兼容部分插件的問題…… v1.0.2：修正actionscript、aspnet、batch匹配問題 v1.0.1：修正正則錯誤……（行内代碼c++匹配）

.Net環境下運行JavaScript淺談
type: item
date: 2015-11-28T09:56:00+00:00
description: 今天更新小玲的洛奇英雄傳功能的時候遇到了瓶頸。原本是直接用HeroesDB的API，但因為群裡人嫌棄，打算換成VindictusManual。這一換，問題來了…… 下載了VindictusManual的js，包含了所有物品的生成與歸類。然後自己寫了個搜索和輸出的js，放進網頁運行了一下，效果很不錯。打算直接投入c#使用…… 原本小玲的登入就用了騰訊WebQQ的js，代碼類似： MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl(); sc.AllowUI = false; sc.UseSafeSubset = true; sc.Language = "JScript"; sc.AddCode(Resources.hash.ToString()); 然而……AddCode一直報錯啊喂！！這MSScriptControl是IE6的js處理引擎吧？！太坑爹了…… 後來幾經輾轉，換了Jurassic、Jint、IronJS等幾個處理引擎，但是效果都不太理想。特別是Jurassic，等了一分鐘才添加完js文件——不得不說輸出倒是挺正常的。IronJS則是根本沒法用……，倒是Jint是一個很棒的引擎，處理效率比Jurassic快了幾十倍不說，還支持將js的函數存至c#裡方便之後Invoke。不過說是說快了不少，實際上添加完VindictusManual的js還是用了好幾秒，有些耽誤事。 直到Javascript.Net的出現……真是大救星好嘛！！！處理任何腳本幾乎都只要2位數，毫秒！僅需要var engine = new Noesis.Javascript.JavascriptContext();就可以var obj = engine.Run("javascript code");運行任意js代碼嚕！ 總之這玩意是神器……算是安利一發吧哈哈哈哈……

文字類遊戲引擎
type: item
date: 2015-11-25T06:23:00+00:00
description: 很久之前的一個設想啦，就是類似很久以前挖泥巴一樣的那種文字類遊戲，或者是現在的大部分視覺小說遊戲（嗯，Visual Novel，AKA Galgame...） 玩家每到一個場景都有不同的分支選項，通過選擇不同的劇情分支最終走向不同的結局。 為了讓小玲可玩性、互動性更強一些——別天天釣魚……昨天也是給小玲寫了這麼一個功能……其實倒也是挺成功的，只是最後……嗯…… 一開始不知道從何下手，想畫圖描述劇情又懶……就拿了Visio來玩……不過倒是更麻煩惹……還自己去定義了圖形[此處應有笑哭表情] 也就是這麼個樣子的圖，還挺直觀的。每個故事版右上角都有編號，利用編號達到不同劇情切換的功能…… 但因為做起來實在是麻煩，就又寫了個讀取EXCEL表格生成代碼的工具。Excel每行都是一個故事版，第一列是劇情，之後每兩列表達的都是跳轉號碼和選項，大大簡化了劇情製作的工序…… 正當我滿心成就感的時候……craft提出了一個叫talkit的東西……[此處應有笑哭表情x3]…… 簡直是神器好不好！生成的json也非常實用，功能幾乎和我想要的一模一樣，甚至更多一些……只不過生成的代碼雖然好用，但和我所需的代碼相差實在太大，昨天奮戰一個下午+晚上才寫出這套系統的我……臣妾真的做不到啊QAQ！ 我覺得……咱還是以後有緣再用這個好了……應該使用的上的，看起來都很激動人心_(:з」∠)_