Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Barry
/
esp8266-Mud
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
27c9cd56
authored
2018-04-27 02:13:03 -0700
by
Barry
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Added wifi handler for web setup.
1 parent
2d5255ad
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
258 additions
and
69 deletions
commands.py
help/help.txt
main.py
mudserver.py
rooms/outside.py
wifiweb.py
commands.py
View file @
27c9cd5
global_aliases
=
{
'n'
:
'north'
,
's'
:
'south'
,
'e'
:
'east'
,
'w'
:
'west'
,
'u'
:
'up'
,
'd'
:
'down'
,
'l'
:
'look'
,
}
class
CommandHandler
(
object
):
def
tokenize_params
(
self
):
...
...
@@ -45,18 +55,89 @@ class CommandHandler(object):
return
True
def
parse
(
self
,
id
,
cmd
,
params
,
room
,
mud
,
players
):
def
who
(
self
):
self
.
mud
.
send_message
(
self
.
id
,
""
)
self
.
mud
.
send_message
(
self
.
id
,
"-------- {} Players Currently Online --------"
.
format
(
len
(
self
.
players
)))
for
pid
,
player
in
self
.
players
.
items
():
self
.
mud
.
send_message
(
self
.
id
,
" "
+
player
[
"name"
])
self
.
mud
.
send_message
(
self
.
id
,
"---------------------------------------------"
.
format
(
len
(
self
.
players
)))
self
.
mud
.
send_message
(
self
.
id
,
""
)
return
True
def
go
(
self
):
# store the exit name
ex
=
self
.
params
.
lower
()
.
strip
()
# if the specified exit is found in the room's exits list
if
ex
in
self
.
room
.
get_exits
():
# go through all the players in the game
for
pid
,
pl
in
self
.
players
.
items
():
# if player is in the same room and isn't the player
# sending the command
if
self
.
players
[
pid
][
"room"
]
==
self
.
players
[
self
.
id
][
"room"
]
\
and
pid
!=
self
.
id
:
# send them a message telling them that the player
# left the room
self
.
mud
.
send_message
(
pid
,
"{} left via exit '{}'"
.
format
(
self
.
players
[
self
.
id
][
"name"
],
ex
))
# update the player's current room to the one the exit leads to
loaded
=
self
.
load_room
(
self
.
room
.
get_exits
()[
ex
])
if
loaded
==
None
:
self
.
mud
.
send_message
(
id
,
"An invisible force prevents you from going in that direction."
)
return
True
else
:
self
.
players
[
self
.
id
][
"room"
]
=
self
.
room
.
get_exits
()[
ex
]
self
.
room
=
loaded
# go through all the players in the game
for
pid
,
pl
in
self
.
players
.
items
():
# if player is in the same (new) room and isn't the player
# sending the command
if
self
.
players
[
pid
][
"room"
]
==
self
.
players
[
self
.
id
][
"room"
]
\
and
pid
!=
self
.
id
:
# send them a message telling them that the player
# entered the room
self
.
mud
.
send_message
(
pid
,
"{} arrived via exit '{}'"
.
format
(
self
.
players
[
self
.
id
][
"name"
],
ex
))
# send the player a message telling them where they are now
self
.
mud
.
send_message
(
id
,
"You arrive at '{}'"
.
format
(
self
.
room
.
get_title
()))
# the specified exit wasn't found in the current room
else
:
# send back an 'unknown exit' message
self
.
mud
.
send_message
(
id
,
"Unknown exit '{}'"
.
format
(
ex
))
return
True
def
alias
(
self
,
command
):
if
command
in
global_aliases
:
return
global_aliases
[
command
]
if
'aliases'
not
in
self
.
players
[
self
.
id
]:
self
.
players
[
self
.
id
][
"aliases"
]
=
{}
if
command
in
self
.
players
[
self
.
id
][
"aliases"
]:
return
self
.
players
[
self
.
id
][
"aliases"
][
command
]
return
command
def
parse
(
self
,
id
,
cmd
,
params
,
room
,
mud
,
players
,
load_room
):
self
.
id
=
id
self
.
cmd
=
cmd
self
.
params
=
params
self
.
tokenize_params
()
self
.
room
=
room
self
.
mud
=
mud
self
.
players
=
players
self
.
load_room
=
load_room
self
.
cmd
=
self
.
alias
(
cmd
)
try
:
method
=
getattr
(
self
,
cmd
)
if
self
.
cmd
in
self
.
room
.
get_exits
():
self
.
params
=
self
.
cmd
+
" "
+
self
.
params
self
.
cmd
=
"go"
method
=
getattr
(
self
,
self
.
cmd
)
return
method
()
except
AttributeError
:
mud
.
send_message
(
id
,
"Unknown command '{}'"
.
format
(
self
.
cmd
))
return
False
...
...
help/help.txt
View file @
27c9cd5
...
...
@@ -2,5 +2,6 @@ Commands:
say <message> - Says something out loud, e.g. 'say Hello'
look - Examines the surroundings, e.g. 'look'
go <exit> - Moves through the exit specified, e.g. 'go outside'
who - Lists all players currently connected
save - Saves your character
quit - Saves your character then closes the connection
\ No newline at end of file
...
...
main.py
View file @
27c9cd5
...
...
@@ -25,13 +25,15 @@ import time
# import datetime
#import io
import
json
import
machine
# import the MUD server class
from
mudserver
import
MudServer
from
commands
import
CommandHandler
print
(
'STARTING MUD
\r\n\r\n\r\n
'
)
flash_button
=
machine
.
Pin
(
0
,
machine
.
Pin
.
IN
,
machine
.
Pin
.
PULL_UP
)
rooms
=
{}
# stores the players in the game
...
...
@@ -62,7 +64,7 @@ def load_room(room_name):
def
save_object_to_file
(
obj
,
filename
):
with
open
(
filename
,
'w'
,
encoding
=
'utf-8'
)
as
f
:
f
.
write
(
json
.
dumps
(
obj
,
ensure_ascii
=
False
))
f
.
write
(
json
.
dumps
(
obj
))
def
load_object_from_file
(
filename
):
try
:
...
...
@@ -78,7 +80,9 @@ def prompt(pid):
# main game loop. We loop forever (i.e. until the program is terminated)
while
True
:
gc
.
collect
()
if
flash_button
.
value
()
==
0
:
break
# pause for 1/5 of a second on each loop, so that we don't constantly
# use 100% CPU time
time
.
sleep
(
0.001
)
...
...
@@ -97,6 +101,8 @@ while True:
# go through any newly connected players
for
id
in
mud
.
get_new_players
():
# add the new player to the dictionary, noting that they've not been
# named yet.
# The dictionary key is the player's id number. We set their room to
...
...
@@ -105,8 +111,9 @@ while True:
players
[
id
]
=
{
"name"
:
None
,
"room"
:
None
,
"inventory"
:
None
,
"inventory"
:
{}
,
"prompt"
:
"> "
,
"aliases"
:
{},
}
# send the new player a prompt for their name
...
...
@@ -124,8 +131,11 @@ while True:
for
pid
,
pl
in
players
.
items
():
# send each player a message to tell them about the diconnected
# player
mud
.
send_message
(
pid
,
"{} quit the game"
.
format
(
if
players
[
id
][
"name"
]
!=
None
:
mud
.
send_message
(
pid
,
"{} quit the game"
.
format
(
players
[
id
][
"name"
]))
else
:
save_object_to_file
(
players
[
id
],
"players/{}.json"
.
format
(
players
[
id
][
"name"
]))
# remove the player's entry in the player dictionary
del
(
players
[
id
])
...
...
@@ -143,7 +153,9 @@ while True:
# if the player hasn't given their name yet, use this first command as
# their name and move them to the starting room.
if
players
[
id
][
"name"
]
is
None
:
if
command
.
strip
()
==
''
or
command
is
None
:
mud
.
send_message
(
id
,
"Invalid Name"
)
continue
loaded_player
=
load_object_from_file
(
"players/{}.json"
.
format
(
command
))
if
loaded_player
is
None
:
players
[
id
][
"name"
]
=
command
...
...
@@ -204,65 +216,12 @@ while True:
players
[
id
][
"name"
],
params
))
# 'look' command
elif
cmd_handler
.
parse
(
id
,
command
,
params
,
rm
,
mud
,
players
):
pass
# 'go' command
elif
command
==
"go"
:
# store the exit name
ex
=
params
.
lower
()
# store the player's current room
rm
=
load_room
(
players
[
id
][
"room"
])
# if the specified exit is found in the room's exits list
if
ex
in
rm
.
get_exits
():
# go through all the players in the game
for
pid
,
pl
in
players
.
items
():
# if player is in the same room and isn't the player
# sending the command
if
players
[
pid
][
"room"
]
==
players
[
id
][
"room"
]
\
and
pid
!=
id
:
# send them a message telling them that the player
# left the room
mud
.
send_message
(
pid
,
"{} left via exit '{}'"
.
format
(
players
[
id
][
"name"
],
ex
))
# update the player's current room to the one the exit leads to
loaded
=
load_room
(
rm
.
get_exits
()[
ex
])
if
loaded
==
None
:
mud
.
send_message
(
id
,
"An invisible force prevents you from going in that direction."
)
continue
else
:
players
[
id
][
"room"
]
=
rm
.
get_exits
()[
ex
]
rm
=
loaded
# go through all the players in the game
for
pid
,
pl
in
players
.
items
():
# if player is in the same (new) room and isn't the player
# sending the command
if
players
[
pid
][
"room"
]
==
players
[
id
][
"room"
]
\
and
pid
!=
id
:
# send them a message telling them that the player
# entered the room
mud
.
send_message
(
pid
,
"{} arrived via exit '{}'"
.
format
(
players
[
id
][
"name"
],
ex
))
# send the player a message telling them where they are now
mud
.
send_message
(
id
,
"You arrive at '{}'"
.
format
(
rm
.
get_title
()))
# the specified exit wasn't found in the current room
else
:
# send back an 'unknown exit' message
mud
.
send_message
(
id
,
"Unknown exit '{}'"
.
format
(
ex
))
else
:
handler_results
=
cmd_handler
.
parse
(
id
,
command
,
params
,
rm
,
mud
,
players
,
load_room
)
# some other, unrecognised command
else
:
# send back an 'unknown command' message
mud
.
send_message
(
id
,
"Unknown command '{}'"
.
format
(
command
))
prompt
(
id
)
# Start WIFI Setup
if
flash_button
.
value
()
==
0
:
import
wifiweb
\ No newline at end of file
...
...
mudserver.py
View file @
27c9cd5
...
...
@@ -324,7 +324,8 @@ class MudServer(object):
# if there is a problem reading from the socket (e.g. the client
# has disconnected) a socket error will be raised
except
socket
.
error
:
except
Exception
as
e
:
sys
.
print_exception
(
e
)
self
.
_handle_disconnect
(
id
)
def
_handle_disconnect
(
self
,
clid
):
...
...
rooms/outside.py
0 → 100644
View file @
27c9cd5
from
.baseroom
import
BaseRoom
class
Outside
(
BaseRoom
):
def
__init__
(
self
):
title
=
"Outside the Tavern"
description
=
"You are standing outside of a simple tavern made of pressed clay and shale roof.
\r\n
The door becons you to come in and have a drink."
exits
=
{
"tavern"
:
"Tavern"
}
look_items
=
{
"tavern"
:
"A roughly constructed building."
,
}
super
(
Outside
,
self
)
.
__init__
(
title
,
description
,
exits
,
look_items
)
wifiweb.py
0 → 100644
View file @
27c9cd5
import
network
import
socket
import
machine
import
time
ap
=
network
.
WLAN
(
network
.
AP_IF
)
ap
.
active
(
True
)
ap
.
config
(
essid
=
'MUD'
)
ap
.
config
(
authmode
=
1
)
class
DNSQuery
:
def
__init__
(
self
,
data
):
self
.
data
=
data
self
.
dominio
=
''
print
(
"Reading datagram data..."
)
m
=
data
[
2
]
# ord(data[2])
tipo
=
(
m
>>
3
)
&
15
# Opcode bits
if
tipo
==
0
:
# Standard query
ini
=
12
lon
=
data
[
ini
]
# ord(data[ini])
while
lon
!=
0
:
self
.
dominio
+=
data
[
ini
+
1
:
ini
+
lon
+
1
]
.
decode
(
"utf-8"
)
+
'.'
ini
+=
lon
+
1
lon
=
data
[
ini
]
#ord(data[ini])
def
respuesta
(
self
,
ip
):
packet
=
b
''
print
(
"Resposta {} == {}"
.
format
(
self
.
dominio
,
ip
))
if
self
.
dominio
:
packet
+=
self
.
data
[:
2
]
+
b
"
\x81\x80
"
packet
+=
self
.
data
[
4
:
6
]
+
self
.
data
[
4
:
6
]
+
b
'
\x00\x00\x00\x00
'
# Questions and Answers Counts
packet
+=
self
.
data
[
12
:]
# Original Domain Name Question
packet
+=
b
'
\xc0\x0c
'
# Pointer to domain name
packet
+=
b
'
\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04
'
# Response type, ttl and resource data length -> 4 bytes
packet
+=
bytes
(
map
(
int
,
ip
.
split
(
'.'
)))
# 4 bytes of IP
return
packet
def
accept_conn
(
listen_sock
):
cl
,
addr
=
listen_sock
.
accept
()
print
(
'client connected from'
,
addr
)
print
(
'Request:'
)
request
=
cl
.
recv
(
2048
)
print
(
request
)
if
'GET /?'
in
request
:
#GET /?network=Volley&networkpass=test
request
=
str
(
request
)
part
=
request
.
split
(
' '
)[
1
]
params
=
part
.
split
(
'?'
)[
1
]
.
split
(
'&'
)
network_param
=
params
[
0
]
.
split
(
'='
)[
1
]
network_pass_param
=
params
[
1
]
.
split
(
'='
)[
1
]
sta_if
=
network
.
WLAN
(
network
.
STA_IF
)
sta_if
.
active
(
True
)
sta_if
.
connect
(
network_param
,
network_pass_param
)
while
sta_if
.
isconnected
()
==
False
:
time
.
sleep
(
1
)
cl
.
send
(
'<html><body>Configuration Saved!<br><br>Network: {} <br>IP Address: {}<br>Password: {}<br><br><br>Restarting Device...</body></html>'
.
format
(
network_param
,
sta_if
.
ifconfig
()[
0
],
network_pass_param
))
cl
.
close
()
time
.
sleep
(
20
)
machine
.
reset
()
return
print
(
'Getting Network STA_IF'
)
sta_if
=
network
.
WLAN
(
network
.
STA_IF
)
print
(
'Starting Network Scan...'
)
avail_networks
=
sta_if
.
scan
()
print
(
'Network Scan Complete'
)
endpoint_string
=
""
for
endpoint
in
avail_networks
:
endpoint_string
+=
"<option value={}>{}</option>"
.
format
(
endpoint
[
0
]
.
decode
(
'latin1'
),
endpoint
[
0
]
.
decode
(
'latin1'
))
response
=
"""
<html>
<head>
<title>Mud Setup</title>
</head>
<body margin='10px'>
<h2>Configure Wifi Network</h2>
<form action='/' method='GET'>
Network: <select name='network' id='network'>
{}
</select><br><br>
Password: <input type='text' name='networkpass' id='networkpass'>
<input type="submit">
</form>
</body>
</html>
\n\n
"""
.
format
(
endpoint_string
)
# rows = ['<tr><td>%s</td><td>%d</td></tr>' % (str(p), p.value()) for p in pins]
# response = html % '\n'.join(rows)
print
(
'Sending Response'
)
cl
.
send
(
response
)
print
(
'Closing Socket'
)
time
.
sleep
(
0.001
)
cl
.
close
()
listen_s
=
None
port
=
80
s
=
socket
.
socket
()
ai
=
socket
.
getaddrinfo
(
"0.0.0.0"
,
port
)
addr
=
ai
[
0
][
4
]
s
.
bind
(
addr
)
s
.
listen
(
1
)
s
.
setsockopt
(
socket
.
SOL_SOCKET
,
20
,
accept_conn
)
iface
=
network
.
WLAN
(
network
.
AP_IF
)
if
iface
.
active
():
print
(
"Web Server daemon started on ws://
%
s:
%
d"
%
(
iface
.
ifconfig
()[
0
],
port
))
# def accept_dns(listen_sock):
# cl, addr = listen_sock.accept()
# print('DNS client connected from', addr)
# try:
# data, addr = udps.recvfrom(1024)
# print("incomming datagram...")
# p=DNSQuery(data)
# udps.sendto(p.respuesta(ip), addr)
# print('Replying: {:s} -> {:s}'.format(p.dominio, ip))
# except:
# print('No dgram')
# # SETUP DNS
# ip=ap.ifconfig()[0]
# print('DNS Server: dom.query. 60 IN A {:s}'.format(ip))
# udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# udps.setblocking(False)
# udps.bind(('',53))
# udps.setsockopt(socket.SOL_SOCKET, 20, accept_dns)
Please
register
or
sign in
to post a comment