Closed9

Land of LispのDice of Doomが動かない

pirafpiraf

Land of Lispをやってみていたんだけど、最終章のDice of Doom(Web版)が動かない。
ちなみに、私が持っているのは初版第三刷
https://github.com/peheenueenuee/land-of-lisp/blob/main/dod-web.cl

正確には、動きはするが、2-3手やるとエラーで止まってしまう。なんでかよく分からないし、そもそもLispのデバッグの勘がないので、なんも分からんになっている。
デバッグの記録をつけてみようと思う

[1]> (load "dod-web")
#P"/land-of-lisp/dod-web.cl"
[2]> (serve #'dod-request-handler)

*** - FUNCALL: undefined function NIL
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of (FDEFINITION 'NIL).
RETRY          :R2      Retry
STORE-VALUE    :R3      Input a new value for (FDEFINITION 'NIL).
ABORT          :R4      Abort main loop
Break 1 [3]>
pirafpiraf
[4]> (serve #'dod-request-handler)

*** - READ: input stream #<IO INPUT-BUFFERED SOCKET-STREAM CHARACTER 0.0.0.0:9010> has reached
      its end
The following restarts are available:
ABORT          :R1      Abort main loop
Break 1 [5]>

こういうエラーが出る時もある
httpのレベルでなんかダメんなってそう

pirafpiraf

そもそもこのserveという関数には問題があり、本(3刷)に載ってるコードそのままではブラウザがhttpだと思ってくれない

(defun serve (request-handler)
  (let ((socket (socket-server 9010)))
    (unwind-protect
      (loop (with-open-stream (st (socket-accept socket))
              (let* ((url (parse-url (read-line st)))
                     (path (car url))
                     (header (get-header st))
                     (params (append (cdr url)
                                     (get-content-params st header)))
                     (*standard-output* st))
                (funcall request-handler path header params))))
      (socket-server-close socket))))

そこでhandlerの方の頭でなんかhttpヘッダぽいものをつけている
一応これで(こんなんで)動く、いやchromeだとダメって言われるけどsafariだとなんか通してくれる

  (princ *pseudo-http-header-string*)

(defparameter *pseudo-http-header-string* "HTTP/1.1 200 OK
Date: Wed, 13 Mar 2024 12:54:39 GMT
Server: Apache/2.4.58 (FreeBSD) OpenSSL/1.1.1t-freebsd mod_perl/2.0.12 Perl/v5.36.3
Last-Modified: Mon, 11 Apr 2005 17:34:29 GMT
Accept-Ranges: bytes
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html


")
pirafpiraf

なんかエラーをコンソールの方に出すやつを作ったぞ
標準出力はブラウザに返す方に使ってしまっているから

(defun princ-error (err)
  (princ err *error-output*)
  (princ #\newline  *error-output*))
pirafpiraf

serveをこんなふうにしてブラウザからのリクエストが見えるようにしたぞ

(defun serve (request-handler)
  (let ((socket (socket-server 9010)))
    (unwind-protect
      (loop 
        (princ-error "### loop start ###")
        (with-open-stream (st (socket-accept socket :timeout 30))
              (let* ((url (parse-url (read-line st)))
                     (path (car url))
                     (header (get-header st))
                     (params (append (cdr url)
                                     (get-content-params st header)))
                     (*standard-output* st))
                (princ-error url)
                (princ-error path)
                (princ-error header)
                (princ-error params)
                (funcall request-handler path header params)))
        (princ-error "### loop end ###"))
      (socket-server-close socket))))

こういうふうなのが出る

### loop start ###
(game.html (CHOSEN . 12))
game.html
((HOST . localhost:9010) (SEC-FETCH-SITE . same-origin) (ACCEPT-ENCODING . gzip, deflate)
 (CONNECTION . keep-alive) (UPGRADE-INSECURE-REQUESTS . 1) (SEC-FETCH-MODE . navigate)
 (ACCEPT . text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8)
 (USER-AGENT .
  Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15)
 (REFERER . http://localhost:9010/game.html?chosen=7) (SEC-FETCH-DEST . document)
 (ACCEPT-LANGUAGE . ja))
((CHOSEN . 12))
### loop end ###
### loop start ###
(game.html)
game.html
((HOST . localhost:9010) (SEC-FETCH-SITE . none) (CONNECTION . keep-alive)
 (UPGRADE-INSECURE-REQUESTS . 1) (SEC-FETCH-MODE . navigate)
 (ACCEPT . text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8)
 (USER-AGENT .
  Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15)
 (ACCEPT-LANGUAGE . ja) (SEC-FETCH-DEST . document) (ACCEPT-ENCODING . gzip, deflate))
NIL
### loop end ###

なんかリロードした時には出るんだけど、そのあとタイルをクリックしたときには出てない気がする
リクエストを受け取れてないってことだろうか
画面はなんか動いてるんだけど

pirafpiraf

すぐ一週間経つ
何もしなくても時間だけはすぎていく
いまserveにもっと簡単なhandlerを渡してみてもやっぱエラーが出るんだよな
あとdodの画面がブラウザにまだ出てるので、キャッシュが効いてんなこれ

pirafpiraf

chromeでアクセスしたら結構動いてるな??この記事、何の意味もなかった可能性ある??
めちゃくちゃ盤面がサーバからプッシュされてくる
なうほどこういうふうに動くものだったのか……

pirafpiraf

タイポ一個直したら最後までプレイできた😭やったね
結局のところ、必要だったのは
-chromeでアクセスする
だけだった。
元々Chromeで動かなくて、Safariじゃないといけなかったのだが、それはもう直っていたっていうことなんだろうか

このスクラップは2ヶ月前にクローズされました