Day 30 – 使用 CDK 創建 Open Unlight 遊戲

https://ithelp.ithome.com.tw/upload/images/20201015/20117701P7SaYXBQqw.png

今天是鐵人賽最後一天,我要來跟大家介紹一個遊戲 Open Unlight 它是一個在 2019 年 7 月 27 日 Open Source 的一個遊戲,剛開源的時候因為沒有安裝說明文件而且有缺少檔案,所以不容易部署在當年的 2019 年 8 月 8 日由 Open Unlight 團隊修改成 legacy-unlight-docker 繼續維護 它應該算是全世界少數 Open Source Server-Client 架構的遊戲之一,Open Source 的遊戲實在是太少了 XD 而為什麼要介紹它呢?因為今天的題目就是教大家用 CDK 把 Unlight 遊戲部署起來呀!

Unlight 遊戲 Server 部署文件

我們今天目標以一台 EC2 在裡面跑 Docker 的架構把整個遊戲伺服器創建起來

建置前我們先看一下 Legacy Unlight Docker (中文) 遊戲專案介紹在文件裡面可以看到遊戲的部署分為 Server 端與 Client 端,而 Server 端有預編譯 Image 可以使用,但是 Client 端沒有需要自己手動編譯,而且 Client 端編譯的時候需要準備字型檔

快速建置指令

而 Open Unlight 其實提供專屬的 UnlightCLI 指令可以幫助快速建立系統,不一定需要用 Legacy Unlight Docker 從 Source Code 編譯

下載指令

指令下載方法

$ gem install unlight-cli

啟動專案

啟動遊戲方法

$ unlight init

導讀完應該就大概知道怎麼把遊戲建立起來了吧!那我們就來寫今天的 CDK 吧!

Unlight 遊戲 CDK

CDK 部分只有寫到 Server 端部署完成,Client 端還是需要進入機器手動編譯的,這點需要注意一下。

建立 Default VPC

今天只有一台 EC2 就直接使用 Default VPC 吧!

const vpc = ec2.Vpc.fromLookup(this, "VPC", {
  isDefault: true,
});

建立 EC2

系統安裝腳本準備

今天建立的 EC2 主要讓 User Data 幫我們把整個環境建立起來並執行遊戲,它會開啟 14 台遊戲主機 1 台資料庫與 1 台 cache 伺服器

更新系統

yum update -y

安裝 vim ruby Nginx

amazon-linux-extras install vim ruby2.4 nginx1 epel -y

安裝 git htop

yum install git htop -y

安裝 docker

amazon-linux-extras install -y docker

下載 docker-compose

curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

加入 docker-compose 執行權限

chmod +x /usr/local/bin/docker-compose

啟動 docker

systemctl restart docker

設定開機啟動 docker

systemctl enable docker

設定 ec2-user 使用 docker

usermod -a -G docker ec2-user

安裝 Nginx

amazon-linux-extras install nginx1 -y

啟動 Nginx

systemctl restart nginx

設定開機啟動 Nginx

systemctl enable nginx

下載 unlight-cli

gem install unlight-cli -N --clear-sources --minimal-deps

執行 unlight init 啟動遊戲

unlight init

CDK 建立 EC2

EC2 部分我們把上面討論的 User Data 放進去讓它開機的時候執行,這是因為服務需求比較大我們開的機器等級是 t3a.medium 更小台應該會跑不動

const instance = new ec2.Instance(this, "Instance", {
  vpc,
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T3A,
    ec2.InstanceSize.MEDIUM
  ),
  machineImage: ec2.MachineImage.latestAmazonLinux({
    generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
  }),
  vpcSubnets: {
    subnetType: ec2.SubnetType.PUBLIC,
  },
  keyName: "KeyPair",
});
instance.userData.addCommands(
  `yum update -y`,
  `amazon-linux-extras install vim ruby2.4 nginx1 epel -y`,
  `yum install tmux git htop -y`,
  `amazon-linux-extras install -y docker`,
  "curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose",
  `chmod +x /usr/local/bin/docker-compose`,
  `systemctl restart docker`,
  `systemctl enable docker`,
  `usermod -a -G docker ec2-user`,
  `amazon-linux-extras install nginx1 -y`,
  `systemctl restart nginx`,
  `systemctl enable nginx`,
  `gem install unlight-cli -N --clear-sources --minimal-deps`,
  `unlight init`
);
new cdk.CfnOutput(this, "instance", {
  value: instance.instancePublicDnsName,
});

設定防火牆

如果要開設給大家玩記得要把 22 port 保護起來呦!一樣我們為了方便 debug 所以先把 22 port 全開

Unlight 遊戲使用的 Port 為 11000 ~ 13000,相信大家應該不會想用前面幾篇教的方法然後用 for 迴圈跑吧 XD

所以今天說明一個之前沒講過用來控制 Security Group 方法 tcpRange 就可以一行幫我們完成 Port 區段的開設

instance.connections.allowFrom(ec2.Peer.anyIpv4(), ec2.Port.tcp(22));
instance.connections.allowFrom(
  ec2.Peer.anyIpv4(),
  ec2.Port.tcpRange(11000, 13000)
);

以上就是今天的 CDK 教學!就這麼簡單!

Unlight 遊戲 Server 部署測試

寫完後我們就來執行今天的 CDK 吧!cdk deploy 把它執行下去!

查看系統是否有正常跑起來

部署完後我們就可以登入進去輸入 docker ps 看看系統是否有跑起來拉! 如下資訊就可以看到系統是正常執行的情況

  • 14 台遊戲主機
  • 1 台資料庫
  • 1 台 cache 伺服器

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-31-43-71 ~]$ docker ps
CONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS              PORTS                      NAMES
ae55da85c62f        openunlight/legacy-server:latest   "server xmlsocket"       4 minutes ago       Up 23 seconds       0.0.0.0:11999->11999/tcp   openunlight_xmlsocket_1
dbd1591f84b9        openunlight/legacy-server:latest   "server raid_rank 12…"   4 minutes ago       Up 23 seconds       0.0.0.0:12070->12070/tcp   openunlight_raid_rank_server_1
5d491c301bcb        openunlight/legacy-server:latest   "server data_lobby 1…"   4 minutes ago       Up 22 seconds       0.0.0.0:12032->12032/tcp   openunlight_data_server_1
92189a119d6e        openunlight/legacy-server:latest   "server lobby 12002"     4 minutes ago       Up 28 seconds       0.0.0.0:12002->12002/tcp   openunlight_lobby_server_1
ca1c6b1795ba        openunlight/legacy-server:latest   "server matching 120…"   4 minutes ago       Up 23 seconds       0.0.0.0:12018->12018/tcp   openunlight_match_server_1
d502e85a13de        openunlight/legacy-server:latest   "server game 12008"      4 minutes ago       Up 22 seconds       0.0.0.0:12008->12008/tcp   openunlight_game_server_1
a615ab3896ae        openunlight/legacy-server:latest   "server global_chat …"   4 minutes ago       Up 27 seconds       0.0.0.0:12020->12020/tcp   openunlight_global_chat_server_1
f1fc99c578dd        openunlight/legacy-server:latest   "server raid_data 12…"   4 minutes ago       Up 31 seconds       0.0.0.0:12100->12100/tcp   openunlight_raid_data_server_1
97eb265c132f        openunlight/legacy-server:latest   "server chat 12012"      4 minutes ago       Up 29 seconds       0.0.0.0:12012->12012/tcp   openunlight_chat_server_1
0d7d7fe736cc        openunlight/legacy-server:latest   "server raid 12050"      4 minutes ago       Up 28 seconds       0.0.0.0:12050->12050/tcp   openunlight_raid_server_1
7bf3e0aeaea9        openunlight/legacy-server:latest   "server raid_chat 12…"   4 minutes ago       Up 21 seconds       0.0.0.0:12090->12090/tcp   openunlight_raid_chat_server_1
7899ae49d6b2        openunlight/legacy-server:latest   "server authenticati…"   4 minutes ago       Up 22 seconds       0.0.0.0:12001->12001/tcp   openunlight_auth_server_1
92c136738e17        openunlight/legacy-server:latest   "server watch 12080"     4 minutes ago       Up 29 seconds       0.0.0.0:12080->12080/tcp   openunlight_watch_server_1
b4fd0bec724b        openunlight/legacy-server:latest   "server quest 12005"     4 minutes ago       Up 28 seconds       0.0.0.0:12005->12005/tcp   openunlight_quest_server_1
58625fbb5e55        mysql:5.7                          "docker-entrypoint.s…"   4 minutes ago       Up 26 seconds       3306/tcp, 33060/tcp        openunlight_db_1
c60470b7c2f3        memcached:1.5.16-alpine            "docker-entrypoint.s…"   5 minutes ago       Up 29 seconds       11211/tcp                  openunlight_memcached_1

部署與編譯 Client

如前面所說因為 Open Unlight 遊戲的 Client 需要依靠資料庫才可以被 build 出來,所以大家需要跟我一起進入機器手動把 Client 端 build 起來

字體檔

字體檔需要大家找一下把它放到 /home/ec2-user/OpenUnlight/fonts 裡面,要準備的字體如:

語言 必要字體
繁體中文 cwming.ttf (cwTeXMing 明體), wt004.ttf (王漢宗特明體), nbr.ttf

nbr.ttf 是一個名為 Bradley Gratis 的字體,但 Unlight 是有客製化過的。

編譯 Client

準備好字體檔後,就可以來跑 client 建置腳本了,其實只要把字體檔準備好差不多就好了,執行以下指令

$ export ROOT_DIR="/home/ec2-user/OpenUnlight"
$ git clone https://github.com/unlightcpa/Unlight-Images.git OpenUnlight/assets
$ mkdir ${ROOT_DIR}/OpenUnlight/dist
$ mkdir ${ROOT_DIR}/OpenUnlight/fonts

$ docker run --rm -v ${ROOT_DIR}/assets:/assets \
                  -v ${ROOT_DIR}/dist:/app/dist \
                  -v ${ROOT_DIR}/fonts:/app/fonts \
                  -e LANGUAGE=tcn \
                  openunlight/legacy-builder compile-client

結果會出現在 dist 資料夾裡面

$ ls -all OpenUnlight/dist/
total 17136
drwxrwxr-x 2 ec2-user ec2-user       43 Oct 14 17:22 .
drwxrwxr-x 5 ec2-user ec2-user       83 Oct 14 17:11 ..
-rw-r--r-- 1 root     root         1976 Oct 14 17:22 index.html
-rw-r--r-- 1 root     root     17539965 Oct 14 17:22 Unlight.swf

Host Client

有了 Unlight.swf 與 index.html 後就可以把檔案放到我們前面安裝的 Nginx 裡面拉! 它的結構需要如:

dist
├── Unlight.swf
├── index.html
└── public
    ├── config.xml
    ├── image/
    ├── news.xml
    └── sound/
  • image 與 sound
    • 在 OpenUnlight/assets 可以找到它
  • config.xml 與 news.xml

不過其實我有準備好腳本,執行它就可以了!

$ sudo cp /home/ec2-user/OpenUnlight/dist/index.html /home/ec2-user/OpenUnlight/dist/Unlight.swf /usr/share/nginx/html/
$ sudo cp -r /home/ec2-user/OpenUnlight/assets/public /usr/share/nginx/html/
$ sudo wget https://raw.githubusercontent.com/unlightcpa/Unlight/master/app/client/public/news.xml.orig -O /usr/share/nginx/html/news.xml
$ sudo wget https://raw.githubusercontent.com/unlightcpa/Unlight/master/app/client/public/config.xml.orig -O /usr/share/nginx/html/config.xml

在開始前需要記得修改 /usr/share/nginx/html/config.xml 把裡面的 localhost 修改成自己的 EC2 網域或是 IP

https://ithelp.ithome.com.tw/upload/images/20201015/20117701JIwwIvdaGO.png

小錯誤:架設起來的 index.html 會有一個 swfobject.js 找不到雖然不會影響開啟不過如果看到覺得煩可以修改一下到 CloudFlare CDN

https://cdnjs.cloudflare.com/ajax/libs/swfobject/2.2/swfobject.js

測試遊戲

超興奮的打開網址就可以看到登入介面囉!

https://ithelp.ithome.com.tw/upload/images/20201015/20117701lYnRGfRvOu.png

趕緊註冊一下遊戲帳號 https://ithelp.ithome.com.tw/upload/images/20201015/20117701ojDxbwFi4y.png

註冊成功,如此就可以確定資料庫串接也是正常的 https://ithelp.ithome.com.tw/upload/images/20201015/20117701WEZAZ8Owre.png

開始玩遊戲吧!(誤 https://ithelp.ithome.com.tw/upload/images/20201015/20117701yvpMM7KPKE.png

最後

謝謝大家這 30 天的陪伴,不管你是一開始就看我教學文的朋友或是看到分享才進來觀看的朋友,希望這 30 天的教學文對於一個剛學習 AWS CDK 的朋友有幫助,因為我知道中文教學文其實還是一個偏少的一個情況,所以寫中文就是希望讓母語中文的朋友在學習上可以減少阻礙,另外如果大家對我的系列文章有興趣,歡迎大家關注我的部落格謝謝大家拉 ~