2013年3月29日 星期五

雙線發展的發展

2013 年正式把同事分為公司組及客戶組,實行雙線發展。到目前已三個月。回顧這段時間的情況,更加鞏固我認為要專注的看法。

頭三個月,客戶的項目少,客戶組的同事總不能游手好閒,因此被安排處理公司組的工作。但為了能儘快讓同事能回復崗位處理客戶方面的應用,而公司組的應用又大不到要兩三位編程同事共同開發,所以他們製作的都是非常簡單的應用程式。往往是兩三星期內搞定的規模。至於為何要儘快回復崗位?這是關乎開發的流程問題。我以往的編程習慣是一開始便埋機寫代碼,邊做邊想結構、邏輯、處理方法,甚少寫開發文件或記錄。對於資源少、時間趕的環境來說,哪有時間寫文件。這個做法的問題是要一氣呵成,要是半途出家處理客戶的應用,回過頭來便要重新跟之前的思想接軌,需要花點時間。更甚者是發現自己功能提升,希望用新的結構或方法推倒重來,浪費之前的功夫。

一直以來,我只會安排一位編程加一位美工負責自家項目。突然人手多了,便要急急忙忙找題材,還要夠小;變成了為做而做的格局。造出來的成品,很大機會是沒有市場,到頭來投資化為烏有。亦由於準備的時間不足,同事們在只有概念的情況下便要落 Code 畫圖,到某個時刻,才發現想法不通,需要另尋出路,開發時間也一再拖長,跟原先快速完成的目標違背或本末倒置。

或者是我的能力出了問題吧。再續…。

2013年3月28日 星期四

甭 Jailbreak 的 Team Awesome 金錢修改

Team Awesome Gems Cheat without Jailbreak

細女喜歡玩《Team Awesome》這套遊戲。對於三歲的小女孩,當然是經常 Game Over。爸爸是時候幫她一把。

利用 iExplorer 打開 iPad 上遊戲目錄中的 Documents,沒有檔案。這意味著數據儲存在 Library/Preferences 內,亦即是 com.ezone.Awesome.plist。用 TextWrangler 打開 plist,簡單清楚看到 var|gems 一行,後方的數字正正是標題畫面中顯示的數值。修改後儲存並拷回原位,重新啟動遊戲。大功告成!

2013年3月27日 星期三

甭 Jailbreak 的 Temple Run 2 存檔移植

Transferring Temple Run 2 Save Data without Jailbreak

大女兒很喜歡玩《Temple Run 2》,白天玩,黑天玩。甚至連收費版的《Brave》也購買了。玩到有一點分數,足夠解開所有角色。家中有兩台 iPad 安裝了這個遊戲,有時孺女在用她的 iPad 時,她會改用另一台。可是遊戲進度顯得落後得多,於是我嘗試把她的儲檔移植到另一台 iPad 上。

利用 iExplorer 打開 iPad 的《Temple Run 2》。受 Apple 指引的影響,存檔這類無法重生的數據,必定在 Documents 目錄內。很明顯 gamedata.txt 就是存檔。用 TextWrangler 打開,內容是 JSON 格式,而且目前的代幣清楚易見 (coinCount)。不過,這麼出名的遊戲,當然不會這麼容易被修改。我沒有深究如何能成功修改。只想達到目的,把 gamedata.txt 拷到另一 iPad 上執行,結果非常順利,所有數據都被移植了。

以下是 88890744 金的存檔:
{"hash":"53d689e10ecacc33217a9019e3f8453e","data":{"version":7,"Players":[{"v":1,"pid":1,"bestScore":91056,"bestCoinScore":204,"bestSpecialCurrencyScore":0,"bestDistanceScore":2678,"lifetimePlays":3,"lifetimeCoins":204,"lifetimeSpecialCurrency":0,"lifetimeDistance":3682,"coinCount":88890744,"specialCurrencyCount":88889387,"activePlayerCharacter":0,"gameCenterNeedsUpdate":true,"artifactsPurchased":[45],"artifactsDiscovered":[],"objectives":[2,1,5,4,0],"powersPurchased":[0],"randomSeed":43955370,"numberResurectsUsed":0,"hashID":null,"Buffs":[],"objectivesActiveData":[{"Title":"Gem Collector","IconNamePre":"","IconName":"","DescriptionPre":"Find a gem","Description":"Found a gem","Points":1,"Hidden":false,"CanEarnMoreThanOnce":false,"Difficulty":10,"T":"CollectSpecialCurrency","TT":"PerRun","FT":"None","SV":1,"EarnedSV":0,"PID":9,"GCID":"com.imangi.templerun2.gems1"},{"Title":"High Roller","IconNamePre":"","IconName":"","DescriptionPre":"Score 100,000 points","Description":"Scored 100,000 points","Points":1,"Hidden":false,"CanEarnMoreThanOnce":false,"Difficulty":10,"T":"Score","TT":"PerRun","FT":"None","SV":100000,"EarnedSV":0,"PID":7,"GCID":"com.imangi.templerun2.score100000"},{"Title":"Stingy","IconNamePre":"","IconName":"","DescriptionPre":"250m collecting no coins","Description":"250m collecting no coins","Points":1,"Hidden":false,"CanEarnMoreThanOnce":false,"Difficulty":5,"T":"Distance","TT":"PerRun","FT":"WithoutCoins","SV":250,"EarnedSV":0,"PID":6,"GCID":"com.imangi.templerun2.distance250nocoins"}]}],"Characters":[{"v":1,"displayname":"Guy Dangerous","cid":0,"gear":[0,-1,-1,-1],"u":true,"uc":1200,"ct":"Coin","pvi":0,"art":[-1,-1,-1],"pid":0},{"v":1,"displayname":"Scarlett Fox","cid":1,"gear":[0,-1,-1,-1],"u":false,"uc":5000,"ct":"Coin","pvi":1,"art":[-1,-1,-1],"pid":0},{"v":1,"displayname":"Barry Bones","cid":2,"gear":[0,-1,-1,-1],"u":false,"uc":15000,"ct":"Coin","pvi":2,"art":[-1,-1,-1],"pid":0},{"v":1,"displayname":"Karma Lee","cid":3,"gear":[0,-1,-1,-1],"u":false,"uc":25000,"ct":"Coin","pvi":3,"art":[-1,-1,-1],"pid":0},{"v":1,"displayname":"Montanna Smith","cid":4,"gear":[0,-1,-1,-1],"u":false,"uc":25000,"ct":"Coin","pvi":4,"art":[-1,-1,-1],"pid":0},{"v":1,"displayname":"Francisco Montoya","cid":5,"gear":[0,-1,-1,-1],"u":false,"uc":25000,"ct":"Coin","pvi":5,"art":[-1,-1,-1],"pid":0},{"v":1,"displayname":"Zack Wonder","cid":6,"gear":[0,-1,-1,-1],"u":false,"uc":25000,"ct":"Coin","pvi":6,"art":[-1,-1,-1],"pid":0}],"ShowTutorial":false,"SMT":true,"ShowFriendMarkers":true,"SoundVolume":0.5,"MusicVolume":0.5,"LikeFB":false,"LikeTw":false,"LastPromoNumber":0,"TwitterURL":"http://bit.ly/TempleRun2","TwitterMessage":"I got {0} points while escaping from a Giant Demon Monkey in Temple Run 2. Beat that! {1}","ReviewBegEnable":true,"HSCCI":false,"HSAS":false,"HSPS":false,"HSNAS":false,"HSNPS":false}}

2013年3月26日 星期二

Disallowed Parent Path

有熟客找我替他們的網頁加入 Checkbox,並把 Checkbox 的內容包含在電郵通知中。有源代碼提供,是一件容易辦到的事,只是時間比較急趕。

一如以往,他們沒有測試服務器提供,只好用自家的臨時服務器,測試修改好的程式。可是遇到「Disallowed Parent Path」錯誤。查證後得悉在 IIS 5.0 下預設為打開的 Parent Path,到了 IIS 6.0 是預設為關閉,所以才導致問題出現。只要到 IIS 內設定一下即可。

2013年3月25日 星期一

Apple Configurator


最近有新客戶向我們查詢,希望給員工使用的 iPad 只能執行指定程式,其他的一律禁用。那時我不知道如何達到這個願望。然而,從一位在 Apple 任職的員工得知 Mac App Store 有一個免費 Apple Configurator 的軟件,能同時依照設定安裝到 30 台 iOS 裝置上。其功能還有:指定使用者、指定執行的應用程序、密碼、電郵、VPN、Proxy...等。實際測試過後,真能滿足客人的願望。

2013年3月22日 星期五

在 Apple TV 上看風行網


網友 Keith Li 在 Facebook 貼了一條連結 http://mactivityhongkong.blogspot.hk/2012/10/apple-tv.html。簡單的手動設定 DNS 到 210.129.145.150 便能連接國內主要的影片網。還有內子最喜歡的「風行網」。


這樣,就能在 Apple TV 看我喜歡的《Robotics Notes》。

2013年3月21日 星期四

Prototype 製作



兩個月前提供了一個新意念給客戶,他們覺得不錯。現在差不多快落實了。今天想到了新的處理方法,希望先造個「Prototype」體驗一下。檢查手上的 MCU,最方便的是 ATmega-128,但要重建開發環境。使用 Virtualbox 能達成。

開發環境重建了,硬件準備好了,接線也準備好了,就是在運作上出了問題。AVRDUDE 傳回「avrdude: stk500_2_ReceiveMessage(): timeout」。原先以為自製的 COM Port 線出了狀況,檢查結果一切正常;懷疑是 Virtualbox 問題,找台 Windows 7 的 PC 試驗,情況沒有改善;難道是 ATmega-128 已經無法寫入?還好,家中有 N 年前日本空運過來的新板。接上後問題仍在。似乎已經轉進牛角尖,日後再續。

2013年3月20日 星期三

Virtualbox 分享目錄

Virtualbox Share Folder

之前一直搞不好 Virtualbox 跟主機的檔案分享功能,今天花時間一試,結果成功了,原來方法很簡單。在 Virtualbox VM 的設定中跳轉到「Shared Folders」,點右中方的「+」號圖示,選擇想要分享的主機目錄。啟動 Windows XP 後,選 Virtualbox 的「Devices」選單中的「Install Guest Additions...」並依指示安裝。完成後重啟 Virtualbox。打開「連線網絡磁碟機」,選「瀏覽」。在「VirtualBox Shared Folders」內揀選要連接的磁碟機。我習慣使用最尾的代號,減少日後加減磁碟機時對代號的影響。

2013年3月19日 星期二

CoreBluetooth[WARNING] Unknown error

今天,TRI Team 成員發現到傳輸問題,原本 46 字符的數據,到達藍牙後只剩頭 18 字符。在 The new iPad 上測試,會出現:

CoreBluetooth[WARNING] Unknown error: 10

奇怪的是,若數據只有數字時,則能突破 18 大關。追查下去,問題在 [CBPeripheral writeValue: forCharacteristic: type:] 引起。網上沒有解決辦法,只好自行修改。原本 BLE mini SDK 裡是這樣寫:

[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];

我把它改成以 16 字符斬件。結果能解決問題:

char *byteArray = (char *)[data bytes];
int length = [data length];
int offset = 0;
while (offset < length) {

int size = (length-offset);
if (size > 16) {size = 16;}

NSData *chunk = [NSData dataWithBytes:byteArray+offset length:size];
[peripheral writeValue:chunk forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
offset += size;
}

2013年3月18日 星期一

解決 Samsung Apps 的空白錯誤

Samsung Apps Unknown Error (Solved)

收到一位用戶的查詢,指在 Galaxy Note II LTE 上利用《Samsung Apps》無法下載《B.Duck Camera》,會彈出空白的錯誤,不知如何解決。雖然這是《Samsung Apps》的問題,但畢竟跟公司作品有點關聯,也嘗試替用戶解決問題。

在公司的 Galaxy Note II LTE 上剛巧也試出相同錯誤,其間有提示指要認證三星帳號,所以估計是這裡設定不對。問題是介面沒有任何幫忙,協助我解決問題。只好自己找找。最後在「設定」中找到「加入帳戶」。


再點「三星帳戶」。

依指示輸入資料,認證電郵便不難解決問題。

2013年3月17日 星期日

兩指拉動的 UIScrollView

UIScrollView Scroll by Two Fingers
《AMIGO Controller》的介面已經增加到四頁:終端機、動作控制台、動作編輯器、即時動作調校,操作變得越走越複雜。由於四個頁面是用 UIScrollView 包裹,而頁面本身亦少不免有拖拉動作發生,系統很容易誤判是最外層 UIScrollView 的操作,使用起來很不方便。為了解決這個問題,我把大 UIScrollView 的單手拉頁手勢改為雙指。在建立 UIScrollView 物件後加入以下程序便可:
 //  Make scroll view scroll by two fingers
 for (UIGestureRecognizer *gestureRecognizer in scrollView.gestureRecognizers)  {
  if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] == NO)  {continue;}

  UIPanGestureRecognizer *panGestureRecognizer = (UIPanGestureRecognizer *)gestureRecognizer;
  [panGestureRecognizer setMinimumNumberOfTouches:2];
 }

2013年3月16日 星期六

雙擊 UIButton

Double Click on UIButton

《AMIGO Controller》的介面設計花了很多心血,希望使用者能得心應手。考慮了很久,思考如何播放動作及修改動作。最後決定單擊「動作」按鈕播放動作,雙擊則顯示選單。

首先,在建立 UIButton 處加入:
[button addTarget:self action:@selector(repeatClicked:withEvent:) forControlEvents:UIControlEventTouchDownRepeat];

之後加入以下內容:
- (void)repeatClicked:(UIButton *)button withEvent:(UIEvent *)event {
    PHLog(@"[MotionViewController buttonClicked] Tag: %d", button.tag);
    UITouch *touch = [[event allTouches] anyObject];
    int tapCount = [touch tapCount];
    if (tapCount < 2) {return;}

    // TODO: Send motion data to motion editor and switch view
}

2013年3月15日 星期五

在 Objective-C 及 Javascript 中使用 JSON

Sending JSON Data between Objective-C and Javascript

開發《AMIGO Controller》時用上跟多新的技術。HTML 是常用的東西。就像是修改 Servo 設定的介而就用上了 HTML,好處是方便改動畫面設計。當要儲存設定內容時,透過 HTML 內的 Javascript 準備好所需數值,然後傳回 JSON 格式的資料到 Objective-C 中。可是資料被轉換為 Thread-safe 格式,使得在 Objective-C 中無法成功轉換 JSON 內容到 NSDictionary。解決方法如下:

NSString *JSONString = [threadSafeString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

這樣就能把﹪內容轉回正常字串。順帶一提,在 iOS 5 開始,Objective-C 本身已經能解開 JSON 內容,方法如下:

NSData *data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

2013年3月14日 星期四

擷取 Raspberry Pi 畫面

Raspberry Pi Screen Capture

Raspberry Pi 突然無法啟動,彈出很多錯誤訊息,估計是不當關機造成。最方便的解決方法是重裝系統,反正已經有更新版推出。

完成安裝後,登入 GUI 介面,想把畫面擷取下來。網尋一下,知道可用 ImageMagick 達成。上年替國內客人開發的後台也用過這個工具。在 Raspberry Pi 的安裝方法是:

sudo apt-get install imagemagick

想要擷取畫面時在 LX Terminal 下輸入 import -window root screen.png 即可。

2013年3月13日 星期三

拉闊圖書館.三:認識九型人格

Introduction to Enneagram

剛完成了第三課的《拉闊圖書館》。是次題目為《認識九型人格》,同樣由我主講。十年前在教會夫婦班學習了《九型人格》,是一門很有趣的學問。今天在公司介紹給同事,希望大家了解不同型號的人有不同的運作模式,從而增加彼此的包容性,也能發揮各性格的長處。明白為何老闆要排列得整整齊齊、構圖要左右對稱、空白位置要有仔細的紋理、圖案使用高對比度色彩;為何同事 A 思路這麼清楚、學習能力這麼強、脾氣這麼好;為何同事 B 會三分鐘熱度、會博學多才...等等。

今次準備的雖然不多,但都算讓同事有初步的認識。結尾時也分享了一些《子平八字》的應用,反而引起了大家的興趣。看來第五節《拉闊圖書館》將會是《認識子平八字》的課呢!

2013年3月12日 星期二

BLE mini 終端測試

BLE mini Terminal Test

TRI Team 的組員給了機體主板給我進行測試,旨在確認主板+藍牙+iPad 能成功達致雙向溝通。接駁好後,發現 iPad 向主板的溝通沒有問題;然而主板向 iPad 的溝通也溝極也不通。那麼要先找出是主板問題、藍牙問題、還是 iPad 問題。花了很多時間,終於成功測試。

我個別地把它們接到 PC COM 埠,用 PuTTY 進行試驗。接上主板後,在 PuTTY 上能看到一秒一次的數據輸出。接上藍牙後,在 PuTTY 上能看到 iPad 傳來的數據,可是 PuTTY 發出的,iPad 則收不到。換上另一顆藍牙模組時,終於達成雙向溝通。似乎是之前那顆藍牙出了狀況。不過,把所有東西接在一起後,問題似舊,天呀!究竟問題出在哪裡?

2013年3月11日 星期一

立體打印的 Raspberry Pi 外殼

3D Printed Raspberry Pi Case

拍檔公司添置了 Makerbot Replicator 2,對於作為 Maker 的我,當然要立即試試。在網上找了一個 Raspberry Pi 的外殼 STL 檔拿來打印。相中就是打印出來後的成品,不錯吧!

2013年3月8日 星期五

《little diary》的辣手問題

五行喜木喜火的我,在已火蛇年的春木季節裡,理應運勢好才是。但蛇年剛到,不好的事接踵而來。替客人開發的應用,進度未如理想;自家應用的品質也不夠專業;招聘又沒有進展;營業額還未達標;機體開發呈膠著狀態...

今日則收到 Times Square 的投訴,指《little diary》在很多 iOS 6.1.x 的 iPhone 4 上跑不起來。我立即拿出 iPhone 4, iPhone 5, iPod touch 4G, iPad, The new iPad 及 iPad with Retina Display 進行測試,結果一切正常,十分流暢。iPhone 4 不是最新的 iOS,升級後再試,運作得非常好。客人不會無端端說有問題,而且 App Store 上很多評語也說有當機情況。在 iTunesConnect 中找不到任何 Crash Report。這下子真是一個辣手問題!手上的機完美運行,但其他人的手機則運作不能,沒有錯誤報告,沒有一絲線索,真不知要如何處理...。

2013年3月7日 星期四

亞洲智能手機應用程式頒獎典禮

Asia Smartphone Apps Contest

今日出席了在數碼港舉行的「亞洲智能手機應用程式高峰會暨頒獎典禮」,公司的《Darts Revenge》獲得遊戲及教育類銅獎。除了多謝 WTIA 及 BeyondZ 所有同事之外,更要多謝內子及兩位女兒的支持。這個獎項對於我來說意義重大,是一個很好的鼓勵。我們會繼續開發更多精彩的應用程式,為香港發光出一分力!

2013年3月6日 星期三

外判的惡夢

Nightmare of Out-sourcing

在 2012 第四季的時候,公司的同事不多,只有現時的一半;但客人的項目則多到無法應付。那時我們的策略是先接回來後作安排,當中一個項目就是礙於人手不足而要外判。惡夢從此展開...。

以往聽過不少有外判工作爛尾的情況發生,自已也親身經歷過。主要是編程的部份;美術外判的成效則好得多。其實今次是不想把程序外判,考慮到公司需要賺錢,結果還是結外判出去。為免重蹈覆轍,我再三叮嚀負責同事需要求外判商每星期提交最新代碼。起初進度一切如計劃中進行,只是代碼沒有依規矩提交,說的都是忘記了。如是者一個月過去了、兩個月過去了、三個月過去了,進度慢慢延後,代碼還是照樣忘記了。好不容易得到了上版,但錯誤百出。再追問進度時,外判商頓時人間蒸發,不知所蹤。直到說要因延遲而扣減開發費用時,才能得到即時的回應。之後繼續不了了知。

今次選擇的人已經是拍檔的朋友,見過面也認是一個負責任的人。不過,負責任會因為情況而改變。外判最大的問題在於時間的控制,特別是跟外判商計算的時間有出入時更易發生問題。大多數外判商報價都是以工作需時來計算。一旦超出預算,就變成沒有收入的一天。從機會成本角度看,更少了一天抓錢的機會,變相失去兩天收入。就算是一個負責任的人,也很容易會委曲求全,變成不負責任的人。問題是,事到如今,要怎樣收拾爛攤子呢?我沒有可行的答案,只有兩個選擇:一是繼續白天「鵝」黑天「鵝」;二是由自己團隊頂上而已...。

2013年3月5日 星期二

檢查 httpd.conf

Validate httpd.conf

服務器的 httpd.conf 是經常改動的設定檔案之一。有時需要重啟系統才知設定的句法是否正確,原來簡單用 httpd -t 便能作出檢查,也避免因語法錯誤而導致開機出現問題。

2013年3月4日 星期一

利用 GPX 檔進行座標測試

Testing Location by GPX Settings

有一個新 iPhone 項目用上了 GPS 全球定位系統來運行,之前已提交給 Apple 審批。一個星期後,Apple 要求我提交應用示範的影片,好讓她們明白應用的實際運作。

起初不知道如何拍攝這條片段,估計是用模擬器來達成,拿著手機及 MacBook 周圍走是比較麻煩吧。話雖如此,但我只懂在模擬器設定現時位置,卻不了解如何進行移動位置的測試。幸好,找到了方法。原來只要在項目中加入 GPX 檔案。內裡格式如下:

<?xml version="1.0"?>
<gpx>
<wpt lat='22.325882' lon='114.214103'><name>Start Point</name></wpt>
<wpt lat='22.323381' lon='114.214296'><name>End Point</name></wpt>
</gpx>

我建立了 Location.gpx 並填上內容,當中的 lat 及 lon 就是座標。座標地址可在 Google Maps 的地圖上點滑鼠右鍵選「這裡有甚麼?」。

啟動模擬器後,點擊在 Xcode 除錯欄上的「箭咀」圖案。這時會見到 GPX 檔的名稱,這裡是 Location。選擇它便會依照 GPX 內的地點,由第一個跑到第二個、再跑到第三個。經由這個方法,我終於能測試到應用,拍下所需要的片段,提交到 Apple 審批。希望新的應用在很快的日子能跟大家見面。

2013年3月3日 星期日

亞洲智能手機應用程式大賽.總決賽

Asia Smartphone Apps Contest Finalist

小弟的 iPad 系 Kinect 型遊戲能夠打入「亞洲智能手機應用程式大賽」的總決賽,實在很榮幸。過去也有一些參與過的作品得到各大大小小的獎項,都是參與了其中一部份;沒有一個像《Darts Revenge》般的反映大,得到大家的認同確是一個鼓舞。

2013年3月2日 星期六

iOS 5.x Viewport Fix

最近在《little diary》遇到一個問題,相同的 html 在 iOS 5.x 及 iOS 6.x 中有著不同的顯示效果。這是由於系統在處理 Viewport 時出現的錯誤。為了更正這個錯誤,只好在 html 內加以修正。以下是修正用的代碼:
//  Viewport scale fix
function viewportFix()  {
 var userAgent = navigator.userAgent;
 if (!userAgent.match(/iPhone/i))  {return;}
 
 var osIndex = userAgent.indexOf("OS ");
 if (osIndex < 0)  {return;}
 
 var osVersion = userAgent.substr(osIndex+3, 3).replace("_", ".");
 if (Number(osVersion.charAt(0)) != 5)  {return;}
 
 //  It is iOS version 5.x, fix it!
 var metaArray = document.getElementsByTagName("meta");
 for (i=0; i<metaArray.length; i++)  {
 if (metaArray[i].name == "viewport")  {continue;}
  metaArray[i].content = "initial-scale=0.5, minimum-scale=0.25, maximum-scale=4.0";
 }
}

2013年3月1日 星期五

使用 PHP GD 偵測白色矩形的結果

Result of White Rectangle Detection

今次要達到的目標其實很簡單,就是要偵測出圖片中白色方形的位置、尺寸及角度。上圖是同事利用 OpenCV 偵測出來的結果。下圖是我花了一天時間自行開發的偵測結果。

只用了 PHP GD、簡單的影像處理功能、細心思考出來的邏輯。已經能達到想要的成果。利害吧!其實來來去去都是那幾道板斧 ^_^)v