Compare commits

...

191 Commits

Author SHA1 Message Date
9d9fa13340 Clean up some 2026-02-11 10:13:22 -08:00
36953062d0 Update todo list 2026-02-11 09:59:09 -08:00
5a99a01eed Refactor timeouts 2026-02-10 19:34:54 -08:00
09bee9627c Fix recoil 2026-02-10 19:29:30 -08:00
96153b9a74 Shot ships fall with gravity 2026-02-10 19:27:50 -08:00
22ab464f5d Refactor shooting and drawing 2026-02-10 19:05:27 -08:00
b54853559f WIP: toggle gravity effect per ship 2026-02-10 16:08:18 -08:00
af8e222045 WIP: move multiple ships 2026-02-10 16:01:34 -08:00
7f07c94c82 Add another ship 2026-02-07 14:38:27 -08:00
94df5140f8 Add cannon recoil animation 2026-02-06 14:34:18 -08:00
df6cf1f75c Update ship appearance 2026-02-06 13:36:14 -08:00
0d63f87e39 Update todo list 2026-02-06 13:09:50 -08:00
3bb5536820 Add recoil velocity 2026-02-06 13:06:46 -08:00
340b30c8dc Handle multiple edge collision in a buggy way 2026-02-06 12:55:08 -08:00
4f9db0a940 Fix cannon length 2026-02-05 14:54:51 -08:00
c783394d01 Increase ship radius? 2026-02-05 14:50:45 -08:00
a13a03e031 Add todo list 2026-02-05 13:37:36 -08:00
3194245309 Move drawing the shot out of the Shoot system 2026-02-05 13:21:57 -08:00
6074b36c99 Remove unused function 2026-02-05 11:49:33 -08:00
d278da060b Move shooting into a system 2026-02-05 11:48:11 -08:00
418fd716b0 Make gun rotation a system 2026-02-05 11:17:06 -08:00
c708dadde0 Move function into Move object 2026-02-05 10:21:50 -08:00
70f958606d Clean up 2026-02-05 10:11:02 -08:00
424cb0f150 Remove unused duplicate functions 2026-02-04 13:49:12 -08:00
d89909e7bf Organize wall elements 2026-02-04 13:05:26 -08:00
93937df1fd Remove idea 2026-02-04 12:53:16 -08:00
6d7214dd46 Comment out all remaining console messages
search and replace with Vim command `:%s/console.log/\/\/ console.log/`
2026-02-04 12:44:40 -08:00
66a044cd2a Remove commented-out console messages
search and replace with Vim command `:%s/\n.*\/\/ console.log.*//`
2026-02-04 12:41:41 -08:00
52e7fd9f9b Calculate reflection using vectors instead of functions? 2026-02-04 10:19:04 -08:00
fae1fd255f Place contact point just outside wall shape 2026-02-02 14:27:48 -08:00
93157f17dd WIP: don't go through walls? 2026-02-02 10:27:19 -08:00
965ed86ed6 WIP: try to fix issue with isAcute function 2026-01-31 11:34:44 -08:00
478c90e398 Something is off in my vector calculations 2026-01-30 13:45:20 -08:00
89cf20e35a WIP: more rounding 2026-01-30 13:25:51 -08:00
d2a8758fb8 WIP: rounding position values 2026-01-30 10:55:07 -08:00
8198fc7b63 WIP: slide along edge but still fall through sometimes 2026-01-26 16:28:10 -08:00
0b6f7a55c0 Clean up 2026-01-26 16:02:23 -08:00
de0052aa0a Think I got it 2026-01-26 14:51:25 -08:00
6f580b2b77 WIP: almost got vector calc 2026-01-26 13:36:23 -08:00
5bb861c376 WIP: Bouncing working but still not perfect 2026-01-24 13:19:43 -08:00
ccc6dc1335 WIP: bounce off corners 2026-01-24 12:57:58 -08:00
853728624a Refactor 2026-01-23 18:22:05 -08:00
435eb0b128 Pull away from contacted walls 2026-01-23 16:20:04 -08:00
7408005ed2 Clean up 2026-01-23 15:29:49 -08:00
aaff3571af Clean up Move.update() 2026-01-23 15:08:37 -08:00
176fd98cb5 Remove unnecessary conditional branches 2026-01-23 14:58:38 -08:00
e1cfff39f0 Find the bounce vector 2026-01-23 14:48:28 -08:00
55f6328d3f WIP: bounce off walls 2026-01-22 13:26:34 -08:00
b509ba12ea WIP: bounce off walls 2026-01-22 12:30:23 -08:00
4b692194ae WIP: figure out normal vector but i don't th ink i need to 2026-01-21 19:18:47 -08:00
112c100057 WIP: slide along wall on collision 2026-01-21 14:16:34 -08:00
20bcd976a8 WIP: handle vertical and horizontal walls 2026-01-20 16:59:04 -08:00
2e17234daf WIP: Velocity while in contact with edge 2026-01-20 16:46:10 -08:00
ac9684f4cf WIP: Velocity while in contact with edge 2026-01-20 16:27:57 -08:00
c6ed409915 WIP: ECS 2026-01-19 14:28:09 -08:00
00f2243f03 WIP 2026-01-19 13:06:59 -08:00
616c8184d0 Add limit for angular velocity 2026-01-17 15:23:59 -08:00
d779f802a6 Rotate gun with torque and angular acceleration/velocity 2026-01-17 13:25:00 -08:00
12d9d8ae95 Add gravity 2026-01-17 12:22:13 -08:00
b68f63b379 Clean up 2026-01-17 10:20:32 -08:00
0fad07d341 Remove unused function 2026-01-17 10:01:13 -08:00
f0ddd4e13a Remove unused function 2026-01-17 09:59:43 -08:00
bbb6cd2c07 Update todo list 2026-01-17 09:33:06 -08:00
965287bcf4 WIP: bullets hit walls 2026-01-17 09:16:44 -08:00
e027291ec8 Fast bullets 2026-01-16 16:56:55 -08:00
ca9ceebd64 WIP: landing 2026-01-10 12:20:00 -08:00
50a851eb2f WIP: adjusting edge collision distance 2026-01-09 10:38:32 -08:00
c250275b1d Revert "WIP: landing"
This reverts commit c8d17b7d46.
2026-01-08 12:40:11 -08:00
c8d17b7d46 WIP: landing 2026-01-08 12:24:18 -08:00
0e4da0fc67 Set indics back to default on reset 2026-01-08 11:11:36 -08:00
da2b1d9a6f WIP: on landing; on collision, color only local wall 2026-01-08 11:05:20 -08:00
4fd9688d53 Remove unused variables 2026-01-08 10:12:52 -08:00
69a0a1dcdd Refactor map struct 2026-01-08 10:10:36 -08:00
c8b1d9c8f6 Clean up 2026-01-08 09:19:10 -08:00
ed83435218 Clean up ship update function 2026-01-07 18:37:50 -08:00
3fa1e8f722 Fix indent 2026-01-07 18:13:43 -08:00
da1bebe4f2 Rename variable 2026-01-07 18:06:54 -08:00
b81f0a8565 Refactor 2026-01-07 15:39:27 -08:00
b9884ba077 WIP 2026-01-07 15:27:51 -08:00
d17d0f0a08 Refactor function 2026-01-07 13:33:22 -08:00
625cae288c Clean up 2026-01-07 13:24:43 -08:00
5c5c76f9a1 Clean up 2026-01-07 12:58:06 -08:00
e9a86c532e Clean up 2026-01-05 10:00:15 -08:00
2c89910ee8 Clean up 2026-01-05 09:38:45 -08:00
1de687b3f1 Refactor edge collision detect function 2026-01-05 09:22:36 -08:00
d9ab0fa1fd Fix bound s between 0 and 1 2026-01-05 09:05:30 -08:00
b3f6d79c01 edgeCollisionPosition already accounts for the ship radius 2026-01-04 23:23:53 -08:00
df2eb64ed5 WIP: edge collision position 2026-01-04 23:15:59 -08:00
2f2a82c46f Fix edges facing ship calc 2026-01-04 18:50:17 -08:00
607486d308 WIP: What is s and t? swapping them seems to work 2026-01-04 17:47:14 -08:00
d6dddc25db WIP: edge segments 2026-01-04 16:52:48 -08:00
a0f580da95 WIP: Add edge collision back 2026-01-04 11:01:01 -08:00
f3db10ac68 Refactor 2026-01-04 10:21:49 -08:00
406c5d1357 Simplify 2026-01-03 16:23:43 -08:00
8db51f8870 Refactor 2026-01-03 13:53:05 -08:00
607eaa187e Fix s and t calculations 2026-01-03 13:34:12 -08:00
0868c953a3 Corner collisions 2026-01-03 12:03:59 -08:00
d45575db7c WIP: forward collision points 2026-01-02 09:31:24 -08:00
b9b744d10f WIP: perpendicular line 2026-01-01 13:46:29 -08:00
c4c0fdd86d WIP: corner collision position 2025-12-31 15:06:22 -08:00
65c4c69f21 WIP: collision corners 2025-12-31 13:12:26 -08:00
c4c8667d4f WIP: collision corners 2025-12-31 12:03:02 -08:00
08c71c05e6 Land on legs 2025-12-29 16:11:43 -08:00
6723e5f5af WIP: land with gear down 2025-12-29 14:30:41 -08:00
109d1aa6fe WIP: gear down with G key 2025-12-29 09:07:41 -08:00
2d72c7f83e WIP: land 2025-12-28 16:28:04 -08:00
e1e2c479af Clean up line intersection function 2025-12-28 14:35:39 -08:00
e8cc4e5241 Clean up 2025-12-28 14:23:22 -08:00
4903812ca1 Handle horizontal and vertical bases 2025-12-28 14:16:25 -08:00
1ab48b58c3 WIP: some cleanup 2025-12-28 13:27:21 -08:00
38c01d27bf WIP: place ship in final collision position 2025-12-28 13:18:48 -08:00
790c267957 WIP: found collision position 2025-12-28 11:38:14 -08:00
bb193630b9 WIP 2025-12-26 21:47:45 -08:00
46167340be WIP: add a circle to the end of the line 2025-12-26 16:40:44 -08:00
b836b1f92b WIP: draw normal lines 2025-12-26 15:13:44 -08:00
b8df14625c WIP: position touching on collision 2025-12-26 12:03:41 -08:00
c9b7c62365 WIP: don't overlap wall on collision 2025-12-26 11:20:29 -08:00
d75c8f1b0f WIP: position after a collision 2025-12-25 20:37:59 -08:00
d13392fef6 WIP: altitude foot point coords 2025-12-25 19:16:01 -08:00
722e8172ab Land 2025-12-25 16:57:10 -08:00
d732fe0bf1 WIP: landing 2025-12-25 10:01:48 -08:00
63e9c45490 WIP: landing 2025-12-25 08:59:53 -08:00
be61acb030 Light up bg on collision 2025-12-24 09:17:41 -08:00
803402beef Update todos 2025-12-24 09:11:02 -08:00
1fd87f8351 Add inverse walls 2025-12-23 17:34:37 -08:00
b6bc696823 Inverse? 2025-12-23 16:41:50 -08:00
d65e5c2b34 Add R key to restart 2025-12-22 15:05:14 -08:00
f7984595cc Add a 3-wall map 2025-12-21 16:55:33 -08:00
32c1d0e56d Pull collection out of function 2025-12-21 16:30:35 -08:00
d0369ca229 Rename some function params for clarity 2025-12-21 16:21:31 -08:00
19a7a26f1b Don't check corners if edge collision, and vise versa 2025-12-21 16:08:53 -08:00
962e1e4094 Refactor 2025-12-21 15:56:09 -08:00
1a7d6233d8 Fix corner collision detection 2025-12-21 15:21:02 -08:00
60ac7f137b Add additional maps 2025-12-21 14:06:07 -08:00
5b594d369b Add additional walls 2025-12-21 13:42:00 -08:00
5868ef2b24 WIP: multiple walls 2025-12-21 12:54:01 -08:00
2c2226d09f Add pointermove event to print pointer coordinates 2025-12-21 10:30:05 -08:00
1c2f35c87b Clean up 2025-12-21 09:15:24 -08:00
a6fde9e567 Fix cannon rotation 2025-12-21 08:47:38 -08:00
eb9c805786 Simplify collision triangle update function 2025-12-20 15:35:20 -08:00
8f963ab98c Remove unneeded variable 2025-12-20 15:23:44 -08:00
5089a30a3b Add missing call to update collision triangles 2025-12-20 15:19:30 -08:00
e7f098dedf Rename variable 2025-12-20 15:13:12 -08:00
273ed43a51 Refactor 2025-12-20 15:06:16 -08:00
f6974d43f4 Refactor long line 2025-12-20 14:29:13 -08:00
95c45ac7c6 Refactor to find starting edges dynamically 2025-12-20 14:20:34 -08:00
6d7669ac10 Stop reading keys after collisions until a keyup event 2025-12-20 13:12:56 -08:00
5d02620b55 Add a toggle for drawing collision lines 2025-12-20 12:58:57 -08:00
a8f9cce90e Restart after crashing with a keydown event 2025-12-20 12:54:13 -08:00
50a20982a4 Move collision detection code into its own function 2025-12-20 08:40:41 -08:00
1f782f75aa Clean up some code 2025-12-20 08:25:02 -08:00
f9a191048a Stop when all edges have been mapped 2025-12-19 19:27:59 -08:00
fc5a1155dd Remove viewed edges 2025-12-19 18:18:10 -08:00
f3a702cce0 Draw edges 2025-12-19 17:24:16 -08:00
598ecde00e Restart if ship touches wall 2025-12-19 16:48:41 -08:00
fcbae33d51 Only render acute triangles 2025-12-19 14:50:09 -08:00
7b63f0524c Stop bullets when they hit a wall 2025-12-19 13:20:49 -08:00
5a5b4e9272 Modify terrain and remove buttons 2025-12-19 13:05:58 -08:00
8705b5779d Add side collision detection 2025-12-19 12:28:48 -08:00
8b89673b6f Detect corner collisions 2025-12-18 18:08:53 -08:00
29588b36d4 Simplify code 2025-12-18 15:43:41 -08:00
7ad55c07ae Use a class instead of changing direct styles 2025-12-18 15:32:27 -08:00
c3bd622841 Find determinant 2025-12-18 14:45:45 -08:00
2b6fadab29 Remove lines, add polygons 2025-12-18 14:27:05 -08:00
4a44a21395 Rename tank to ship 2025-12-18 11:07:48 -08:00
660bfba1b9 Refactor updateBullets function to simplify 2025-12-18 11:05:51 -08:00
0282a0b721 Move bullets and lines updates to separate functions 2025-12-18 10:47:46 -08:00
a0c804823c Change terrain shape; clean up some 2025-12-18 10:31:38 -08:00
235ea57e81 Draw lines from corners 2025-12-17 18:32:19 -08:00
9e8987fcc0 WIP: collision detection 2025-12-17 17:52:47 -08:00
0b841d8873 Limit ship max speed 2025-12-17 16:59:48 -08:00
9730ff85fb Add debug info 2025-12-17 16:28:36 -08:00
bf807f9e29 Rename file 2025-12-17 15:56:57 -08:00
264cb1dc81 Add key events for arrow and angle bracket keys 2025-12-17 15:51:56 -08:00
5b3710ac4a Add key events for W, A, S, D, Q, E and Space 2025-12-17 13:50:57 -08:00
138a2122e0 Remove comments 2025-12-17 12:53:23 -08:00
b1fd38196e Make bullets originate from end of cannon 2025-12-17 12:51:01 -08:00
60836c9028 Fire bullets in direction of cannon 2025-12-17 12:37:40 -08:00
43f5fccebf WIP: fire bullets 2025-12-17 12:23:52 -08:00
c33c9ec4bc WIP: bullet 2025-12-15 11:24:13 -08:00
b358c2c0c5 Relable buttons 2025-12-14 22:13:07 -08:00
58952cfa88 Add rotating gun 2025-12-14 21:58:14 -08:00
d4e1bf5b9e Add friction 2025-12-13 22:50:42 -08:00
6418c10415 Re-lable buttons 2025-12-13 22:03:47 -08:00
d2163d060b Float around 2025-12-13 22:02:11 -08:00
1baf76d901 Fix velocity by making a vector 2025-12-13 19:42:01 -08:00
88241ad705 Add velocity 2025-12-13 19:10:56 -08:00
37f683e9a5 Output fps 2025-12-13 14:12:37 -08:00
b735a6e124 Update README.md 2025-11-25 16:10:46 -08:00
5c74ee4cbe Update base container image from "bookworm" to "trixie" (Debian 13) (#4)
These changes:

- Update base container image from Bookworm to Trixie Debian
- Update Pandoc version
- Add a `make shell` command

Caveats:

- Uses the "bookworm" version of OpenResty until "trixie" is released

Reviewed-on: #4
2025-11-25 23:56:19 +00:00
c0b54ad843 Publish post 'Test nginx Configuration Directives' (#3)
Sitegen had some problems rendering `$host$request_uri` and `$$ct` so I had to make some changes to the Markdown renderer.

Reviewed-on: #3
2025-06-30 22:49:28 +00:00
14 changed files with 2552 additions and 32 deletions

View File

@@ -1,15 +1,64 @@
FROM openresty/openresty:bookworm-buildpack
FROM buildpack-deps:trixie
WORKDIR /opt/app
ARG version=3.7.0.1
ARG version=3.8.2.1
ARG pkgname=pandoc-$version-1-amd64.deb
ARG pkgurl=https://github.com/jgm/pandoc/releases/download/$version/$pkgname
ARG RESTY_DEB_FLAVOR=""
ARG RESTY_DEB_VERSION="=1.27.1.2-1~bookworm1"
ARG RESTY_LUAROCKS_VERSION="3.12.2"
RUN apt-get update && apt-get install -y \
python3-pygments lua-inotify wget && \
wget -q -O $pkgname $pkgurl && dpkg -i $pkgname && rm $pkgname
RUN wget -qO - https://openresty.org/package/pubkey.gpg | gpg --dearmor > /etc/apt/trusted.gpg.d/openresty-keyring.gpg \
&& chown root:root /etc/apt/trusted.gpg.d/openresty-keyring.gpg \
&& chmod ugo+r /etc/apt/trusted.gpg.d/openresty-keyring.gpg \
&& chmod go-w /etc/apt/trusted.gpg.d/openresty-keyring.gpg \
&& echo "\nTypes: deb\nURIs: https://openresty.org/package/debian\nSuites: bookworm\nComponents: openresty\nEnabled: yes\nSigned-By: /etc/apt/trusted.gpg.d/openresty-keyring.gpg" >> /etc/apt/sources.list.d/debian.sources \
&& DEBIAN_FRONTEND=noninteractive apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
openresty${RESTY_DEB_FLAVOR}${RESTY_DEB_VERSION} \
openresty-resty${RESTY_DEB_FLAVOR}${RESTY_DEB_VERSION} \
openresty-opm${RESTY_DEB_FLAVOR}${RESTY_DEB_VERSION} \
openresty-openssl3${RESTY_DEB_FLAVOR}-dev \
openresty-pcre2${RESTY_DEB_FLAVOR}-dev \
openresty-zlib${RESTY_DEB_FLAVOR}-dev \
&& mkdir -p /var/run/openresty \
&& ln -sf /dev/stdout /usr/local/openresty${RESTY_DEB_FLAVOR}/nginx/logs/access.log \
&& ln -sf /dev/stderr /usr/local/openresty${RESTY_DEB_FLAVOR}/nginx/logs/error.log
# Install LuaRocks
RUN curl -fSL https://luarocks.github.io/luarocks/releases/luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz -o luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
&& tar xzf luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
&& cd luarocks-${RESTY_LUAROCKS_VERSION} \
&& mkdir -p /usr/local/openresty/luajit \
&& ./configure \
--prefix=/usr/local/openresty/luajit \
--with-lua=/usr/local/openresty/luajit \
--with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1 \
&& make build \
&& make install \
&& cd /tmp \
&& rm -rf luarocks-${RESTY_LUAROCKS_VERSION} luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz
# Add additional binaries into PATH for convenience
ENV PATH="$PATH:/usr/local/openresty${RESTY_DEB_FLAVOR}/luajit/bin:/usr/local/openresty${RESTY_DEB_FLAVOR}/nginx/sbin:/usr/local/openresty${RESTY_DEB_FLAVOR}/bin"
# Add LuaRocks paths
# If OpenResty changes, these may need updating:
# /usr/local/openresty/bin/resty -e 'print(package.path)'
# /usr/local/openresty/bin/resty -e 'print(package.cpath)'
ENV LUA_PATH="/usr/local/openresty/site/lualib/?.ljbc;/usr/local/openresty/site/lualib/?/init.ljbc;/usr/local/openresty/lualib/?.ljbc;/usr/local/openresty/lualib/?/init.ljbc;/usr/local/openresty/site/lualib/?.lua;/usr/local/openresty/site/lualib/?/init.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua;./?.lua;/usr/local/openresty/luajit/share/luajit-2.1/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty/luajit/share/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/?/init.lua"
ENV LUA_CPATH="/usr/local/openresty/site/lualib/?.so;/usr/local/openresty/lualib/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so"
WORKDIR /opt/app
# Copy nginx configuration files
COPY nginx.conf /usr/local/openresty${RESTY_DEB_FLAVOR}/nginx/conf/nginx.conf
COPY nginx.vh.default.conf /etc/nginx/conf.d/default.conf
RUN luarocks install sitegen
# needed for sitegen watcher
@@ -35,3 +84,8 @@ RUN mkdir -p /var/www/certs/webdevcat.me \
-addext "subjectAltName=DNS:webdevcat.me,DNS:git.webdevcat.me,DNS:apps.webdevcat.me"
CMD ["sh", "-c", "openresty -p `pwd` -g 'daemon off;'"]
# Use SIGQUIT instead of default SIGTERM to cleanly drain requests
# See https://github.com/openresty/docker-openresty/blob/master/README.md#tips--pitfalls
STOPSIGNAL SIGQUIT

View File

@@ -5,6 +5,9 @@ serve:
docker run --rm -it --init -v $(PWD):/opt/app -p 8080:80 $(image) \
sh -c "openresty -p /opt/app -g 'daemon off;' -c conf/dev.nginx.conf"
shell:
docker run --rm -it --init -v $(PWD):/opt/app -p 8080:80 $(image) bash
build:
$(if $(file), $(docker-run) sitegen build $(file), $(docker-run) sitegen)

View File

@@ -1,23 +1,26 @@
## requirements
`pandoc` utility must be installed
* Docker
- Debian Bookworm:
## up and running
$ apt-get update && apt-get install -y pandoc
## start default openresty
1. Run `docker run --rm -it --init -w /opt -v $PWD:/opt -p 80:80 openresty/openresty:1.27.1.2-0-bookworm-buildpack`
2. Visit `localhost` in web browser.
## start a custom site
### build docker image
### build container image
$ make image-build
### rebuild an existing docker image
### build site
$ make build
### start dev server
$ make serve
Visit `localhost:8080` in web browser
## getting around
### rebuild the container image
$ make image-rm image-build
@@ -27,9 +30,11 @@
### add an index page
#### create the file
$ docker run --rm -w /opt/app -v $PWD:/opt/app miti.sh sitegen page /opt/app index
### add to `site.moon`
#### add to `site.moon`
add "index.md"
@@ -52,15 +57,13 @@
}
}
### build site
### build a single file
$ make build
$ make build file=index.html
### start dev server
### start a shell
$ make
Visit `localhost:8080` in web browser
$ make shell
### start watcher
@@ -86,6 +89,13 @@ example:
$ make deploy
### renew server TSL certs
SSH into server admin account and run:
$ cd www
$ dehydrated --config config -c
## gotchas
### What is error `cosmo failed: [string "..."]:62: cannot resume dead coroutine`?
@@ -109,3 +119,10 @@ Delete your `.sitegen_cache` file.
* use sitecache with pandoc renderer
* draft documents
* treesitter highlighting for moonscript
## todo
* destroy a target ship by shooting them with the cannon
* make corners not bouncy (leave them bouncy for now?)
* wall entities
* ship-ship collision

1
html/.gitignore vendored
View File

@@ -15,4 +15,5 @@ posts/resize-a-qemu-disk-image.html
posts/set-up-a-gitweb-server.html
posts/start-erlangs-dialyzer-with-gui-from-a-docker-container.html
posts/test-mix-task-file-modify.html
posts/test-nginx-conf-directives.html
pygments.css

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

1627
html/images/space.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 53 KiB

117
nginx.conf Normal file
View File

@@ -0,0 +1,117 @@
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}

58
nginx.vh.default.conf Normal file
View File

@@ -0,0 +1,58 @@
# nginx.vh.default.conf -- docker-openresty
#
# This file is installed to:
# `/etc/nginx/conf.d/default.conf`
#
# It tracks the `server` section of the upstream OpenResty's `nginx.conf`.
#
# This config (and any other configs in `etc/nginx/conf.d/`) is loaded by
# default by the `include` directive in `/usr/local/openresty/nginx/conf/nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root /usr/local/openresty/nginx/html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

View File

@@ -0,0 +1,566 @@
{
title: "Test nginx Configuration Directives"
blurb: "We use MoonScript and some Lua packages to write tests for the
directives in our `nginx` configuration files."
}
$index
## Introduction
[`nginx`](https://docs.nginx.com/nginx/admin-guide/web-server/web-server/#rewrite-uris-in-requests)
configuration can contain any number of important directives (redirects and
rewrites, for example) that need to be verified for correctness. We can write
tests for directives and run them against a test server to ensure they are
correct.
To do this, we'll use...
- [MoonScript](https://moonscript.org) and (by extension) [Lua](https://www.lua.org/) programming languages
- `nginx` we'll get from [OpenResty](https://openresty.org/en/), a web platform
created by Chinese developer, [Yichun Zhang](https://agentzh.org/)
- the [Busted testing framework](https://lunarmodules.github.io/busted/)
- the Lua package manager, [LuaRocks](https://luarocks.org/)
- a fantastic little library, [`luajit-curl`](https://bitbucket.org/senanetworksinc/luajit-curl/src/master/),
from Japanese developer [SENA Networks, Inc](https://www.sena-networks.co.jp)
- another great library, written by volunteers, [LuaSocket](https://github.com/lunarmodules/luasocket)
- our favorite container manager, [Docker Engine](https://docs.docker.com/engine/)
## Setup
Since we require LuaRocks, we'll use a Buildpack tag, which comes with it
already installed.
```console
$ docker pull openresty/openresty:bookworm-buildpack
```
Start a server on `localhost`:
```console
$ docker run --rm -it -p 80:80 openresty/openresty:bookworm-buildpack
```
We can visit `localhost` in our browser and we should see the OpenResty splash
page.
![OpenResty default nginx index page](/images/openresty-default-index-page.png)
## Get `nginx` running
First, let's [prepare the directory layout](https://openresty.org/en/getting-started.html#prepare-directory-layout).
```console
$ mkdir -p logs/ conf/conf.d/ html/
```
Next, we copy over [the default `nginx` config file](https://github.com/openresty/docker-openresty?tab=readme-ov-file#nginx-config-files).
```console
$ docker run --rm -it -w /opt -v $PWD:/opt openresty/openresty:bookworm-buildpack \
cp /etc/nginx/conf.d/default.conf /opt/conf.d/
```
Then, we update the root directive in `default.conf`:
::: filename-for-code-block
`conf/conf.d/default.conf`
:::
```diff
location / {
- root /usr/local/openresty/nginx/html;
+ root /var/www;
index index.html index.htm;
```
Now, let's add an index file.
::: filename-for-code-block
`html/index.html`
:::
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title></title>
</head>
<body>
hello world!
</body>
</html>
```
Last, we start `nginx`:
```console
$ docker run --rm -it -p 80:80 \
-v $PWD/conf/conf.d:/etc/nginx/conf.d -v $PWD/html:/var/www \
openresty/openresty:bookworm-buildpack
```
Then, in another console, this should output our index file.
```console
$ curl -v localhost
* Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: openresty/1.27.1.2
< ...
<
<!DOCTYPE html>
<html lang="en">
...
<body>
hello world!
</body>
</html>
```
## Test an HTTP request
If we want to write a test for that request, we need some packages from
LuaRocks. Let's add a `Dockerfile` to build an image with those packages
installed.
### Add a `Dockerfile`
```Dockerfile
FROM openresty/openresty:bookworm-buildpack
WORKDIR /opt/app
RUN luarocks install moonscript
RUN luarocks install busted
RUN luarocks install luajit-curl
RUN luarocks install luasocket
```
Now let's build our image:
```console
$ docker build -t test-nginx .
```
### Write the test
Let's first make a new directory where our tests will live.
```console
$ mkdir spec
```
Our test makes a cURL request against our test server:
::: filename-for-code-block
`spec/nginx_spec.moon`
:::
```moonscript
http = require "luajit-curl-helper.http"
req = (url) ->
request = http.init url
st = request\perform!
error request\lastError! if not st
request
describe "http://localhost", ->
it "sends /index.html", ->
request = req "http://localhost"
assert.same request\statusCode!, 200
assert.same request\statusMessage!, "OK"
assert.same request\body!\match("<body>%s+(.-)%s+</body>"), "hello world!"
```
### Run the test suite
Start the test server. We're going to use `text-nginx`, the image we just
built.
```console
$ ct=$(docker run --rm -d \
-v $PWD/conf/conf.d:/etc/nginx/conf.d \
-v $PWD/html:/var/www \
-v $PWD:/opt/app \
test-nginx)
```
Start the test run:
```console
$ docker exec -t $ct busted
1 success / 0 failures / 0 errors / 0 pending : 0.008246 seconds
```
Stop the test server.
```console
$ docker exec $ct openresty -s stop
```
## Create a `Makefile`
We now have a number of long `docker` commands, let's create a `Makefile`
to make running them easier.
::: filename-for-code-block
`Makefile`
:::
```Makefile
image = test-nginx
image-build:
docker build -t $(image) .
image-rm:
docker image rm $(image)
test:
@ct=$(shell docker run --rm -d \
-v $(PWD)/conf/conf.d:/etc/nginx/conf.d \
-v $(PWD)/html:/var/www \
-v $(PWD):/opt/app \
$(image)); \
docker exec -t $$ct busted; \
docker exec $$ct openresty -s stop
```
Now we can run the test suite with the command `make test`.
## Configure the domain name
Instead of `localhost` we'd like to use an actual domain name. We can do this
with the `--add-host` option. But before we do that, we want to make sure our
container does not have access to the internet, otherwise we might
unintentionally get a response from a domain's server on the internet rather
than from our test server.
### Ensure the test container is offline
We need to create a network that has no external access.
```console
$ docker network create --internal no-internet
```
Now we need to update our `Makefile` to add the test container to our
internal-only network:
```diff
test:
@ct=$(shell docker run --rm -d \
-v $(PWD)/conf/conf.d:/etc/nginx/conf.d \
-v $(PWD)/html:/var/www \
-v $(PWD):/opt/app \
+ --network no-internet \
$(image)); \
```
And now let's add a test in `spec/nginx_spec.moon` to make sure our test
environment is offline:
```moonscript
describe "test environment", ->
it "can't connect to the internet", ->
assert.has_error (-> req "http://example.org"),
"Couldn't resolve host name"
```
Let's run our tests:
```console
$ make test
●●
2 successes / 0 failures / 0 errors / 0 pending : 0.020207 seconds
```
### Replace `localhost` with a custom domain
To use a custom domain name instead of `localhost`, we will need to use the
`--add-host` option for the `docker run` command. Again, we edit `Makefile`:
```diff
test:
@ct=$(shell docker run --rm -d \
-v $(PWD)/conf/conf.d:/etc/nginx/conf.d \
-v $(PWD)/html:/var/www \
-v $(PWD):/opt/app \
--network no-internet \
+ --add-host=domain.abc=127.0.0.1 \
$(image)); \
```
Let's update our test to use the custom domain name:
::: filename-for-code-block
`spec/nginx_spec.moon`
:::
```diff
-describe "http://localhost", ->
+describe "http://domain.abc", ->
it "sends /index.html", ->
- request = req "http://localhost"
+ request = req "http://domain.abc"
assert.same request\statusCode!, 200
```
Verify our tests still pass.
```console
$ make test
●●
2 successes / 0 failures / 0 errors / 0 pending : 0.0224 seconds
```
## Test an HTTP redirect
We want our server to redirect all `http` requests to `https`.
### Write the test
Let's practice a bit of test-driven development and write our test first.
```moonscript
describe "http://domain.abc", ->
it "redirects to https", ->
request = req "http://domain.abc"
assert.same request\statusCode!, 301
assert.same request\statusMessage!, "Moved Permanently"
assert.same request\header!.Location, "https://domain.abc/"
```
We should now have one failing test.
```console
$ make test
●●◼
2 successes / 1 failure / 0 errors / 0 pending : 0.010449 seconds
Failure → .../luajit/lib/luarocks/rocks-5.1/busted/2.2.0-1/bin/busted @ 3
http://domain.abc redirects to https
spec/nginx_spec.moon:24: Expected objects to be the same.
Passed in:
(number) 301
Expected:
(number) 200
```
### Configure `nginx`
We're going to add the redirect directives, as well as a server name for our
domain and the directives for the SSL certificates we will generate.
```diff
+server {
+ listen 80;
+ return 301 https://$host$request_uri;
+}
server {
- listen 80;
+ listen 443 ssl;
+ server_name domain.abc;
+ ssl_certificate /etc/ssl/certs/domain.abc.pem;
+ ssl_certificate_key /etc/ssl/private/domain.abc.pem;
location / {
root /var/www;
index index.html index.htm;
}
```
### Generate self-signed SSL/TLS certs for testing
Add a command to our `Dockerfile` to generate self-signed certificates:
```Dockerfile
RUN openssl req -x509 -newkey rsa:4096 -nodes \
-keyout /etc/ssl/private/domain.abc.pem \
-out /etc/ssl/certs/domain.abc.pem \
-sha256 -days 365 -subj '/CN=domain.abc' \
-addext "subjectAltName=DNS:domain.abc"
```
Rebuild the image:
```console
$ make image-rm image-build
```
We need to update our previous test to use HTTPS instead of HTTP.
::: filename-for-code-block
`spec/nginx_spec.moon`
:::
```diff
-describe "http://domain.abc", ->
+describe "https://domain.abc", ->
it "sends /index.html", ->
- request = req "http://domain.abc"
+ request = req "https://domain.abc"
```
Run tests:
```console
$ make test
●●●
3 successes / 0 failures / 0 errors / 0 pending : 0.017065 seconds
```
## Test reverse proxy a subdomain request to a Unix socket
Let's say we have a running service that connects to a Unix socket. We want to
proxy the requests through `nginx` so that our service can respond to `https`
requests but can leave handling SSL/TLS to `nginx`.
### Configure `nginx`
We'll add another server block to `conf/conf.d/default.conf` for our subdomain,
`git.domain.abc`, with the proxy directives:
```nginx
server {
listen 443 ssl;
server_name git.domain.abc;
location / {
client_max_body_size 1024M;
proxy_pass http://unix:/run/gitea/gitea.socket;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
### Add subdomain to SSL/TLS certs
Next, we need to add our subdomain to the generated SSL certs in the
`Dockerfile`:
```diff
RUN openssl req -x509 -newkey rsa:4096 -nodes \
-keyout /etc/ssl/private/domain.abc.pem \
-out /etc/ssl/certs/domain.abc.pem \
-sha256 -days 365 -subj '/CN=domain.abc' \
- -addext "subjectAltName=DNS:domain.abc"
+ -addext "subjectAltName=DNS:domain.abc,DNS:git.domain.abc"
```
### Add subdomain as a host
Let's assign the loopback address to a variable and then add our subdomain as a
host in our `Makefile`:
```diff
+loopback = 127.0.0.1
test:
@ct=$(shell docker run --rm -d \
-v $(PWD)/conf/conf.d:/etc/nginx/conf.d \
-v $(PWD)/html:/var/www \
-v $(PWD):/opt/app \
--network no-internet \
- --add-host=domain.abc=127.0.0.1 \
+ --add-host=domain.abc=$(loopback) \
+ --add-host=git.domain.abc=$(loopback) \
$(image)); \
```
### Add a test socket server
We need to start up a mock socket server for our test to ensure our request is
being proxied correctly. This is why we needed the LuaSocket library.
Copied and modified from [here](https://github.com/lunarmodules/luasocket/blob/4844a48fbf76b0400fd7b7e4d15d244484019df1/test/unixstreamsrvr.lua),
this should suit our purposes:
::: filename-for-code-block
`spec/unixstreamsrvr.moon`
:::
```moonscript
socket = require "socket"
socket.unix = require "socket.unix"
u = assert socket.unix.stream!
assert u\bind "/run/gitea/gitea.socket"
assert u\listen!
assert u\settimeout 1
c = assert u\accept!
while true
m = assert c\receive!
break if m == ""
print m
```
### Write the test
And now we can add our test:
::: filename-for-code-block
`spec/nginx_spec.moon`
:::
```moonscript
describe "https://git.domain.abc", ->
it "reverse-proxy's a subdomain request to a unix socket", ->
socket = fname: "unixstreamsrvr.moon", dir: "/run/gitea", owner: "nobody"
basepath = debug.getinfo(1).short_src\match"^(.*)/[^/]*$" or "."
seconds = 0.1
os.execute "install -o #{socket.owner} -d #{socket.dir}"
cmd = "su -s /bin/bash -c 'moon %s' %s"
server = io.popen cmd\format "#{basepath}/#{socket.fname}", socket.owner
os.execute "sleep #{seconds}" -- wait for server to start
f = io.popen "find #{socket.dir} -type s -ls", "r"
result = with f\read "*a"
f\close!
assert.truthy result\match "nobody%s+nogroup.+#{socket.dir}/gitea.socket"
req "https://git.domain.abc"
reqheader = with server\read "*a"
server\close!
assert.truthy reqheader\match "Host: git.domain.abc"
```
Because we modified the `Dockerfile`, we need to rebuild our image:
```console
$ make image-rm image-build
```
And if all went well, our test should pass.
```console
$ make test
●●●●
4 successes / 0 failures / 0 errors / 0 pending : 0.131619 seconds
```
## Conclusion
These are just a few examples of how to test `nginx` directives. Using these
tools, we can verify that changes to our server configuration are working the
way we intended.

View File

@@ -23,11 +23,11 @@ span.linenos.special { color: #50fa7b; background-color: #6272a4; padding-left:
.highlight .py-cpf { color: #6272a4 } /* Comment.PreprocFile */
.highlight .py-c1 { color: #6272a4 } /* Comment.Single */
.highlight .py-cs { color: #6272a4 } /* Comment.Special */
.highlight .py-gd { color: #8b080b } /* Generic.Deleted */
.highlight .py-gd { color: #ff5555 } /* Generic.Deleted */
.highlight .py-ge { color: #f8f8f2; text-decoration: underline } /* Generic.Emph */
.highlight .py-gr { color: #f8f8f2 } /* Generic.Error */
.highlight .py-gh { color: #f8f8f2; font-weight: bold } /* Generic.Heading */
.highlight .py-gi { color: #f8f8f2; font-weight: bold } /* Generic.Inserted */
.highlight .py-gi { color: #50fa7b } /* Generic.Inserted */
.highlight .py-go { color: #f8f8f2 } /* Generic.Output */
.highlight .py-gp { color: #50fa7b } /* Generic.Prompt */
.highlight .py-gs { color: #f8f8f2 } /* Generic.Strong */

View File

@@ -1,5 +1,70 @@
Path = require "sitegen.path"
dollar_temp = "z000sitegen_markdown00dollar0000"
-- a constructor for quote delimited strings
simple_string = (delim) ->
import P from require "lpeg"
inner = P("\\#{delim}") + "\\\\" + (1 - P delim)
inner = inner^0
P(delim) * inner * P(delim)
lua_string = ->
import P, C, Cmt, Cb, Cg from require "lpeg"
check_lua_string = (str, pos, right, left) ->
#left == #right
string_open = P"[" * P"="^0 * "["
string_close = P"]" * P"="^0 * "]"
valid_close = Cmt C(string_close) * Cb"string_open", check_lua_string
Cg(string_open, "string_open") *
(1 - valid_close)^0 * string_close
-- returns a pattern that parses a cosmo template. Can be used to have
-- pre-processors ignore text that would be handled by cosmo
parse_cosmo = ->
import P, R, Cmt, Cs, V from require "lpeg"
curly = P {
P"{" * (
simple_string("'") +
simple_string('"') +
lua_string! +
V(1) +
(P(1) - "}")
)^0 * P"}"
}
alphanum = R "az", "AZ", "09", "__"
P"$" * alphanum^1 * (curly)^-1
escape_cosmo = (str) ->
escapes = {}
import P, R, Cmt, Cs, V from require "lpeg"
counter = 0
cosmo = parse_cosmo! / (tpl) ->
counter += 1
key = "#{dollar_temp}_#{counter}"
escapes[key] = tpl
key
patt = Cs (cosmo + P(1))^0 * P(-1)
str = patt\match(str) or str, escapes
str, escapes
unescape_cosmo = (str, escapes) ->
import P, R, Cmt, Cs from require "lpeg"
escape_patt = P(dollar_temp) * P("_") * R("09")^1 / (key) ->
escapes[key] or error "bad key for unescape_cosmo"
patt = Cs (escape_patt + P(1))^0 * P(-1)
assert patt\match(str)
needs_shell_escape = (str) -> not not str\match "[^%w_-]"
shell_escape = (str) -> str\gsub "'", "''"
@@ -19,12 +84,13 @@ write_exec = (cmd, content) ->
fname
-- config command like this in site.moon:
-- require("renderers.markdown").cmd = "pandoc --mathjax >"
class PandocRenderer extends require "sitegen.renderers.markdown"
unescape_cosmo = @unescape_cosmo
escape_cosmo = @escape_cosmo
class PandocRenderer extends require "sitegen.renderers.html"
@escape_cosmo: escape_cosmo
@unescape_cosmo: unescape_cosmo
@parse_cosmo: parse_cosmo
source_ext: "md"
ext: "html"
cmd: "pandoc --mathjax --lua-filter pygments.lua >"
pandoc: (content) => Path.read_file write_exec @@cmd, content

View File

@@ -29,7 +29,6 @@ get_files = (path, prefix=path) ->
files = for file in *files
file\gsub "^#{escape_patt prefix}/?", ""
table.sort files
files
-- strip file extension from filename

View File

@@ -104,6 +104,10 @@ describe "https://miti.sh/posts/", ->
describe "https://miti.sh/posts", ->
it "sends /posts/index.html", ->
with require "sitegen.path"
assert .exists("html/posts/index.html"),
"missing html/posts/index.html (try `make build file=blog.html`)"
request = req "https://miti.sh/posts"
assert.same request\statusCode!, 200
assert.same request\statusMessage!, "OK"

View File

@@ -86,3 +86,11 @@ this code block has no label
assert.same [[<div class="sourceCode" id="cb1"><pre
class="sourceCode heex"><code class="sourceCode elixir"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="op">&lt;.</span>greet name<span class="op">=</span><span class="st">&quot;Jane&quot;</span><span class="op">/&gt;</span></span></code></pre></div>]], out
it "escapes and unescapes double dollar signs", ->
out = flatten_html render [[
```Makefile
$$name
```]]
assert.same [[<div class="highlight"><pre><span></span><code><span class="py-w"></span><span class="py-nv">$$name</span></code></pre></div>]], out