mana.lisp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. ;;; mana.lisp --- Interacting with Mana
  2. ;; Copyright © 2013-2016 Alex Kost <alezost@gmail.com>
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;;
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; Mana is "The Mana World" game <https://themanaworld.org/>.
  17. ;; Some commands for starting mana client and automating boring actions
  18. ;; (like bat daily quest). No, no, i'm not a bot; i just don't like to
  19. ;; press keys while watching my character playing.
  20. ;;; Code:
  21. (in-package :stumpwm)
  22. (defvar *mana-client-name* "manaplus"
  23. "Name of a mana client program.")
  24. (defvar *mana-thread* nil
  25. "A thread used in functions for sending keys to the mana window.")
  26. (defvar *mana-quit-sending-p* nil
  27. "Predicate for defining quit from sending keys to the mana window.")
  28. (defvar *mana-check-window-p* t
  29. "If non-nil, check whether current window is the mana one.")
  30. (defun mana-window-p (win)
  31. "Return T if WIN is mana window."
  32. (string= "manaplus" (window-class win)))
  33. (defun mana-send-keys (keys-list &key (sleep 0.5) loop msg)
  34. "Send keys to the current mana window.
  35. Each object of KEYS-LIST should be suitable for KEYS argument of
  36. `al/send-keys'.
  37. If LOOP is t, send the last keys of KEYS-LIST in a loop.
  38. Show a message MSG if it is specified.
  39. For SLEEP meaning see `al/send-keys'."
  40. (let ((win (current-window)))
  41. (if (or (null *mana-check-window-p*)
  42. (mana-window-p win))
  43. (progn
  44. (setf *mana-quit-sending-p* nil)
  45. (and msg (echo msg))
  46. (setf *mana-thread*
  47. (let ((last (car (last keys-list))))
  48. (sb-thread:make-thread
  49. (lambda ()
  50. (mapc (lambda (obj)
  51. (al/send-keys obj :win win :sleep sleep
  52. :loop (if (eq obj last) loop)
  53. :loop-quit-var '*mana-quit-sending-p*))
  54. keys-list))
  55. :name "sending-keys-to-mana"))))
  56. (echo "Not Mana window."))))
  57. (defcommand mana-attack () ()
  58. "Send attack mixed with movements keys in a loop to the mana window."
  59. (mana-send-keys
  60. (list (lambda ()
  61. (al/get-random-obj '(("a" . 0.7)
  62. ("p" . 0.1)
  63. ("." . 0.05)
  64. ("e" . 0.05)
  65. ("o" . 0.05)
  66. ("u" . 0.05)))))
  67. :sleep (lambda () (al/random-float 0.2 1))
  68. :loop t
  69. :msg "Mana attack begins..."))
  70. (defcommand mana-quick-attack () ()
  71. "Send attack key in a loop to the mana window."
  72. (mana-send-keys
  73. '("a")
  74. :sleep (lambda () (al/random-float 0.1 0.5))
  75. :loop t
  76. :msg "Mana quick attack begins..."))
  77. (defvar *mana-bat-quest-start-keys*
  78. '("n" "t" "Down" "Down" "SPC" "SPC" "Down" "SPC" "SPC" "SPC" "Down" "SPC" "SPC" "SPC" "SPC" "SPC")
  79. "A list of strings for starting the bat quest.")
  80. (defvar *mana-bat-quest-cont-keys*
  81. '("n" "t" "Down" "Down" "SPC" "SPC" "SPC" "SPC")
  82. "A list of strings for continuing the bat quest.")
  83. (defcommand mana-bat-quest-start () ()
  84. "Send keys for starting a talk with Arkim."
  85. (mana-send-keys (list *mana-bat-quest-start-keys*)
  86. :sleep (lambda () (al/random-float 0.7 1.2))
  87. :msg "Bat quest (start) begins..."))
  88. (defcommand mana-bat-quest-cont () ()
  89. "Send keys for continuing a talk with Arkim."
  90. (mana-send-keys (list *mana-bat-quest-cont-keys*)
  91. :sleep (lambda () (al/random-float 0.7 1.2))
  92. :loop t
  93. :msg "Bat quest (continuation) begins..."))
  94. (defcommand mana-bat-quest-full () ()
  95. "Send keys for a full talk with Arkim."
  96. (mana-send-keys (list *mana-bat-quest-start-keys*
  97. *mana-bat-quest-cont-keys*)
  98. :sleep (lambda () (al/random-float 0.7 1.2))
  99. :loop t
  100. :msg "Bat quest begins..."))
  101. (defun mana-thread-alive-p (&optional alive-msg-p dead-msg-p)
  102. "Return T if mana thread is still alive.
  103. Optinally show a message about the state of the thread, according to
  104. ALIVE-MSG-P and DEAD-MSG-P "
  105. (if (and *mana-thread* (sb-thread:thread-alive-p *mana-thread*))
  106. (progn (and alive-msg-p (echo "^b^7*Mana thread is ^2*alive^7*."))
  107. t)
  108. (progn (and dead-msg-p (echo "^b^7*Mana thread is ^B^1*dead^b^7*."))
  109. nil)))
  110. (defcommand mana-state () ()
  111. "Show a state of mana thread."
  112. (mana-thread-alive-p t t))
  113. (defcommand mana-break () ()
  114. "Stop sending keys to mana window."
  115. (when (mana-thread-alive-p nil t)
  116. (setf *mana-quit-sending-p* t)))
  117. (defcommand mana-kill () ()
  118. "Kill mana thread (if `mana-break' doesn't help)."
  119. (when (mana-thread-alive-p nil t)
  120. (sb-thread:terminate-thread *mana-thread*)
  121. (echo "^b^7*Mana thread was ^B^1*killed^b^7*.")))
  122. ;;; mana.lisp ends here