Skip to content

Commit

Permalink
Merge pull request #3 from rasensuihei/mcfunction-0.2
Browse files Browse the repository at this point in the history
mcfunction-0.2
  • Loading branch information
rasensuihei authored Jun 24, 2019
2 parents e6fa91c + a6561a6 commit 5119fcc
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 67 deletions.
86 changes: 74 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,88 @@
# mcfunction-mode

![Screenshot](ss00.png)

Emacs major mode for editing Minecraft mcfunction.

The main features of this mode are Minecraft mcfunction syntax highlighting and interprocess communication (IPC) with the Minecraft server.
The main features of this mode are Minecraft mcfunction syntax highlighting.

**As it is currently under development, there can be significant changes.**

## Setting example

~~~elisp
(require 'mcfunction-mode)
;; Your server.jar location.
(setq mcfunction-server-directory "~/.minecraft/server/")
;; This is a default value.
(setq mcfunction-server-command "java -Xms1024M -Xmx1024M -jar server.jar nogui")
~~~

## Default key bindings
* `C-c C-c` `mcfunction-execute-command`
* `C-c C-e` `mcfunction-execute-command-at-point`

---

(add-to-list 'auto-mode-alist '("\\.mcfunction\\'" . mcfunction-mode))
# mcrcon.el

mcrcon.el is software to communicate with Minecraft RCON server.

*Warning: Minecraft RCON is not thread safe before 1.14.3-pre2.*

## Setup RCON server

Edit `server.properties` file located in the Minecraft server directory.
~~~
rcon.port=25575
enable-rcon=true
rcon.password=PASSWORD
~~~

## Settings example

~~~elisp
(require 'mcrcon)
(setq mcrcon-password "PASSWORD")
;; Another settings.
(setq
;; Default host address.
mcrcon-address "localhost"
;; Default port number.
mcrcon-port 25575
;; Describe packet information.
mcrcon-print-packet-infomation t)
~~~

## Usage

* `M-x mcrcon` to connect to Minecraft RCON server.
* `M-x mcrcon-disconnect` to disconnect from Minecraft RCON server.

### Minecraft command macro `mceval`

~~~ elisp
(mceval "help help")
(mceval "list" (payload)
(string-match "There are \\([0-9]+\\) of a max 20 players online" payload)
(when (equal (match-string 1 payload) "0")
(message "Nobody is here :(")
(mceval "summon creeper 0 10 0 {CustomName:\"{\\\"text\\\":\\\"Player\\\"}\"}")))
~~~

`mceval` does not block processing, and BODY is evaluated when the server responds.

`mceval` must be nested. If you call consecutively in a loop, the Minecraft RCON server will disconnect the client.

## Changelog
### 0.2
* Minecraft RCON client (mcrcon.el) supported.
* The IPC server communication feature has been deprecated.
* More colorful highlights.

## Default key bindings:
* C-c C-c mcfunction-send-string
* C-c C-e mcfunction-execute-command-at-point
* C-c C-k mcfunction-stop-server
* C-c C-r mcfunction-start-server
### 0.1
* First commit.

## TODO
* Connect to server with RCON, not IPC.
* Scanning syntax from the server's help results, It's to use for highlighting and completion.
* datatag <=> sexp conversion.
* Automatic reconnect when disconnected from server.
* More hooks.
133 changes: 78 additions & 55 deletions mcfunction-mode.el
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
;;; mcfunction-mode.el --- Major mode for editing Minecraft mcfunction.
;;; mcfunction-mode.el --- Major mode for editing Minecraft mcfunction -*- lexical-binding: t -*-

;; Copyright (C) 2019 rasensuihei

;; Author: rasensuihei <[email protected]>
;; URL: https://github.com/rasensuihei/mcfunction-mode
;; Version: 0.1
;; Version: 0.2
;; Keywords: languages

;; This program is free software: you can redistribute it and/or modify
Expand All @@ -21,40 +21,34 @@
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; The main features of this mode are Minecraft mcfunction syntax
;; highlighting and interprocess communication (IPC) with the
;; Minecraft server.
;;
;; ;; Settings example:
;; highlighting.

;; Settings example
;; (require 'mcfunction-mode)
;; ;; Your server.jar location.
;; (setq mcfunction-server-directory "~/.minecraft/server/")
;; ;; This is a default value.
;; (setq mcfunction-server-command "java -Xms1024M -Xmx1024M -jar server.jar nogui")
;;
;; (add-to-list 'auto-mode-alist '("\\.mcfunction\\'" . mcfunction-mode))
;;

;; Default keybindings:
;; C-c C-c mcfunction-send-string
;; C-c C-c mcfunction-execute-command
;; C-c C-e mcfunction-execute-command-at-point
;; C-c C-k mcfunction-stop-server
;; C-c C-r mcfunction-start-server
;;
;; TODO: Scanning syntax from the server's help results, It's to use
;; for highlighting and completion.

;; See also:
;; https://github.com/rasensuihei/mcfunction-mode

;;; Code:
(require 'font-lock)
(require 'mcrcon)

(defgroup mcfunction nil
"Major mode for editing minecraft mcfunction."
:group 'languages)

(defface mcfunction-illegal-syntax
'((t (:background "dark red" :underline t)))
(defface mcfunction-syntax-warning
'((((class color) (background light)) (:background "IndianRed1"))
(((class color) (background dark)) (:background "firebrick4")))
"Illegal space face"
:group 'mcfunction)
(defvar mcfunction-illegal-syntax 'mcfunction-illegal-syntax)
(defvar mcfunction-syntax-warning 'mcfunction-syntax-warning)

(defvar mcfunction--font-lock-keywords
(list
Expand All @@ -63,42 +57,37 @@
(1 font-lock-keyword-face))
;; Command
'("\\(^\\|run \\)\\([a-z]+\\)\\>"
(1 font-lock-keyword-face)
(2 font-lock-builtin-face))
;; Selector
(1 font-lock-keyword-face)
(2 font-lock-builtin-face))
;; Syntax warning
'("\\( \s+\\|^\s+\\|\s+$\\|@[aeprs]\s+\\[\\)"
(1 mcfunction-syntax-warning))
;; Selector variable
'("\\(@[aeprs]\\)"
(1 font-lock-type-face))
;; '("\\(@[aeprs]\\)\\[\\([^]]*\\)\\]"
;; (1 font-lock-type-face t)
;; (2 font-lock-doc-face t))
(1 font-lock-variable-name-face))
'("\\(@[aeprs]\\)\\[\\([^]]*\\)\\]"
(1 font-lock-variable-name-face t)
(2 font-lock-constant-face t))
;; Selector arguments
'("\\([a-zA-Z0-9_]+\\)\s*="
(1 font-lock-builtin-face t))
'("\\([,=:]\\)"
(1 font-lock-builtin-face t))
;; (2 default t))
;; Negation char
'("=\\(!\\)"
(1 font-lock-negation-char-face))
'("\\( ,\\|, \\| [ ]+\\|^ +\\)"
(1 mcfunction-illegal-syntax))
(1 font-lock-negation-char-face t))
;; String
'("\"\\(\\\\.\\|[^\"]\\)*\""
(1 font-lock-string-face))
(1 font-lock-string-face t))
;; Line comment
'("^\\(#.*\\)$"
(1 font-lock-comment-face t))
))

(defvar mcfunction-display-server-messages t "Display received server messages on minibuffer.")

(defvar mcfunction-server-command "java -Xms1024M -Xmx1024M -jar server.jar nogui")

(defvar mcfunction-server-directory ".")

(defvar mcfunction-server-working-directory nil "When this is nil, Working directory is mcfunction-server-directory.")

(defconst mcfunction-server-buffer-name "*Minecraft-Server*")

(defvar mcfunction-mode-prefix-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-r" 'mcfunction-start-server)
(define-key map "\C-k" 'mcfunction-stop-server)
(define-key map "\C-c" 'mcfunction-send-string)
(define-key map "\C-c" 'mcfunction-execute-command)
(define-key map "\C-e" 'mcfunction-execute-command-at-point)
map))

Expand All @@ -110,9 +99,15 @@
(defvar mcfunction-mode-hook nil
"This hook is run when mcfunction mode starts.")

(defvar mcfunction--server-state nil "This variable represents the state of the server. Value is nil, 'starting', 'ready' or 'finishing'.")
(defvar mcfunction-mode-syntax-table
(let ((table (make-syntax-table)))
;; (modify-syntax-entry ?# "<" table)
;; (modify-syntax-entry ?\r ">" table)
;; (modify-syntax-entry ?\n ">" table)
table))

(defvar mcfunction--server-message-buffer nil "Buffered server messages.")
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.mcfunction\\'" . mcfunction-mode))

;;;###autoload
(define-derived-mode mcfunction-mode prog-mode "mcfunction"
Expand All @@ -123,6 +118,28 @@
(setq-local comment-start "#")
(setq-local comment-end ""))

(defalias 'mcfunction-execute-command 'mcrcon-execute-command
"Execute Minecraft command STR. HANDLER is a function for server response handle.")

(defalias 'mcfunction-execute-command-at-point 'mcrcon-execute-command-at-point
"Execute Minecraft command at point.")

;;; --- Deprecated ---

(defvar mcfunction-display-server-messages t "Display received server messages on minibuffer.")

(defvar mcfunction-server-command "java -Xms1024M -Xmx1024M -jar server.jar nogui")

(defvar mcfunction-server-directory ".")

(defvar mcfunction-server-working-directory nil "When this is nil, Working directory is mcfunction-server-directory.")

(defconst mcfunction-server-buffer-name "*Minecraft-Server*")

(defvar mcfunction--server-state nil "This variable represents the state of the server. Value is nil, 'starting', 'ready' or 'finishing'.")

(defvar mcfunction--server-message-buffer nil "Buffered server messages.")

(defun mcfunction--server-ready ()
"Return server is completely ready."
(and (eq mcfunction--server-state 'ready)
Expand Down Expand Up @@ -167,9 +184,13 @@
(princ fmt-msg))
(with-current-buffer mcfunction-server-buffer-name
(goto-char (point-max))
(insert msg)
;; (if my-out
;; (insert msg)
(if (not (string-match "Summoned" msg))
(insert msg))
(goto-char (point-max))))))


(defun mcfunction-send-string (str)
"Send STR to minecraft server."
(interactive "MCommand: ")
Expand All @@ -178,18 +199,18 @@
(when (string-equal str "stop")
(setq mcfunction--server-state 'finishing))
(setq mcfunction--server-message-buffer nil)
(with-current-buffer mcfunction-server-buffer-name
(goto-char (point-max))
(insert (concat ">> " str "\n"))
(goto-char (point-max)))
;; (with-current-buffer mcfunction-server-buffer-name
;; (goto-char (point-max))
;; (insert (concat ">> " str "\n"))
;; (goto-char (point-max)))
(process-send-string "mcserver" (concat str "\n")))))

(defun mcfunction-start-server ()
"Start minecraft server."
(interactive)
(setq mcfunction--server-message-buffer nil)
(if (processp (get-process "mcserver"))
(princ "Minecraft server is already running.")
(message "Minecraft server is already running.")
;; else
(let ((default-directory (or mcfunction-server-working-directory
mcfunction-server-directory))
Expand All @@ -200,7 +221,9 @@
(split-string mcfunction-server-command " +")))
(setq server (get-process "mcserver"))
(set-process-filter server 'mcfunction--server-filter)
(set-process-sentinel server 'mcfunction-server-sentinel))))
(set-process-sentinel server 'mcfunction-server-sentinel)
(message "Starting Minecraft server..."))))


(defun mcfunction-server-sentinel (process signal)
"Minecraft server process sentinel function. PROCESS is server process. SIGNAL is server signal(hope \"finished\\n\")."
Expand Down

0 comments on commit 5119fcc

Please sign in to comment.