Giter Club home page Giter Club logo

miniboa's Introduction

Miniboa: a simple Telnet server

build status

downloads

What?

Miniboa is a bare-bones Telnet server to use as the base for a MUD or similar interactive server. Miniboa has several nice features for this type of application.

Features

  • Asynchronous - no waiting on player input or state.
  • Single threaded - light on resources with excellent performance.
  • Runs under your game loop - you decide when to poll for data.
  • Supports 1000 users under Linux and 512 under Windows (untested).
  • Miniboa is compatible with both Python 2.7, and 3.x

Quick Start

First:

pip install miniboa

And then:

from miniboa import TelnetServer
server = TelnetServer()
while True: server.poll()

But you probably want to do something with the connecting/disconnecting clients:

   clients = []


   def on_connect(client):
       client.send("Hello, my friend. Stay awhile and listen.")
       clients.append(client)


   def on_disconnect(client):
       clients.remove(client)


   server = TelnetServer(
       port=3333,
       address='',
       on_connect=on_connect,
       on_disconnect=on_disconnect
       encoding='utf-8')

   while True:
       server.poll()

To use Miniboa, you create a Telnet Server object listening at a specified port number. You have to provide two functions for the server; the first is a handler for new connections and the second is the handler for lost connections. These handler functions are passed Telnet Client objects -- these are your communication paths to and from the individual player's MUD client.

For example, let's say Mike and Joe connect to your MUD server. Telnet Server will call your on_connect() function with Mike's Telnet Client object, and then again with Joe's Telnet Client object. If Mike's power goes out, Telnet Server will call your on_disconnect() function with Mike's Telnet Client object (same exact one).

This will launch a server listening on the default port, that accepts Telnet connections and sends a simple message.

$ telnet localhost 7777
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, my friend. Stay awhile and listen.

Further documentation can be found here.

Copyright

Copyright 2009 Jim Storch
Copyright 2015 Carey Metcalfe
Copyright 2016 Joseph Schilz
Copyright 2018 Jared Miller

miniboa's People

Contributors

cjmayo avatar coal0 avatar gergelypolonkai avatar harlowja avatar hroncok avatar jaschilz avatar michael-lazar avatar pr0ps avatar shmup avatar tizen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

miniboa's Issues

Create example code for a very basic MUD

I would like to create a simple example script for creating a very, very basic MUD.

A list of players.

Players are represented on a simple ascii, ansi colored terrain map:

~~~...........^^^...
~~~~.........^^^....
~~~~~~........^^^^..
~~~~~...........^^^^
~~~.................
....................
....................
....................

Implement movement (n, s, e, w) and say (announced to players in same room), and tell (message to specific players), possibly overall chat (everyone connected).

This should help motivate people getting started with miniboa for MUD use.

miniMUD does a good job of this, with a lot of extra stuff.

Telnet session termination

To end connection I set connection.active to false and remove it from
connections list but it does not cause session termination. That means that
telnet client still thinks it is connected.

Original issue reported on code.google.com by [email protected] on 22 Dec 2009 at 12:19

Make the client class configurable

While writing a telnet-enabled service, I created a lot of helper functions that are related to the clients. Obviously, I soon created a whole class to include these functions, but keeping a list with all the Client objects is a bit cumbersome.

I had an idea in mind to subclass TelnetClient, and add all the methods there, but there is no way to pass this class to TelnetServer. I already made a patch locally to make this possible, are you interested in such a change?

Suggestion

When I am using this module to setup the server, I found I have two choice:

  1. request_will_echo
    connect the server through putty, Input will not display when type in the command until press enter
  2. request_wont_echo
    Input will display when typing, but because the telnet echo is False, the command been input will be replaced by the information server returned.

would you consider add another choice like this :
def request_will_echo(self): self._iac_wont(ECHO) self._note_reply_pending(ECHO, True) self.telnet_echo = True

Color codes are not chosen very happily

For example
^rblue

Should be blue written in red or lue on red background?
I suggest to make all color codes two characters length.
So red become ^rc and blue ^bc. 

Another problem is when you want to enter '^' character. For example I
wanted to print ^a, where a should be red, so string looks like that
"^^ra", which is interpreted as 'reset colors'ra. I found work around by
adding null character, so it looks like that "^\0^ra" and seems to work right.

Best regards
Michal


Original issue reported on code.google.com by [email protected] on 26 Jan 2010 at 11:57

AttributeError when “disconnecting” with Ctrl-C

I just copied the example to a .py file, connected using Linux telnet, and interrupted the connection with Ctrl-C within telnet. The server crashed with this traceback:

Traceback (most recent call last):
  File "/usr/lib64/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/polesz/Projects/c/wmud/wmud/__main__.py", line 28, in <module>
    server.poll()
  File "/home/polesz/Projects/c/wmud/.venv/lib64/python3.6/site-packages/miniboa/async.py", line 179, in poll
    self.clients[sock_fileno].socket_recv()
  File "/home/polesz/Projects/c/wmud/.venv/lib64/python3.6/site-packages/miniboa/telnet.py", line 309, in socket_recv
    self._iac_sniffer(byte)
  File "/home/polesz/Projects/c/wmud/.venv/lib64/python3.6/site-packages/miniboa/telnet.py", line 385, in _iac_sniffer
    self._three_byte_cmd(byte)
  File "/home/polesz/Projects/c/wmud/.venv/lib64/python3.6/site-packages/miniboa/telnet.py", line 484, in _three_byte_cmd
    self._note_local_option(option, False)
AttributeError: 'TelnetClient' object has no attribute '_note_local_option'

Using Python 3.6.1 on Fedora 26, miniboa 1.0.0 is installed through pip.

Missing underscore in _ANSI_CODES

In xterm.py
There is _ANSI_CODES declared but at line 69 there is:
for token, throwaway in ANSI_CODES:
(no underscore at the begining)


Original issue reported on code.google.com by [email protected] on 20 Dec 2009 at 10:32

Python 3.x compatabilty

What steps will reproduce the problem?
1. Attempt to run miniboa with Python 3.x
2.
3.

What is the expected output? What do you see instead? The system is expected to 
start. I get invalid syntax errors.


What version of the product are you using? On what operating system?
Miniboa r42, Python 3.1, Windows 7

Please provide any additional information below.
Python 3.1 requires that all print statements are enclosed in parenthesis.

Original issue reported on code.google.com by [email protected] on 9 Aug 2010 at 1:41

Async is a reserved word in Python 3.7

When trying to use TelnetServer on Python 3.7 the following error occurs:

SyntaxError: invalid syntax
>>> from .async import TelnetServer
  File "<stdin>", line 1
    from .async import TelnetServer

The cause of this is due to async becoming a reserved word in the latest version of Python.

I was able to fix this issue locally by renaming async.py to something else and updating the reference to it in __init__.py

Bug? Problem with telnet embedded command under python3.6

Hi, I have a problem with internal telnetclient commands.

I create a simple script in which I activate a TelnetServer and then, when I connect a terminal, I request the type of terminal connected, using the request_terminal_type () function.

If I run the script with python 2.7, everything works properly.

Under python 3.6, instead, I see spurious characters appear on the terminal with which I am connected and the request for request_terminal_type () is never found.

I tried both xterm terminals and putty terminals, with the same result.

I think I identified the problem in the socket_send () function of the TelnetClient.

In this function, in fact, all that is transmitted to the remote terminal is coded in 'utf-8'.

if PYTHON_2:
     sent = self.sock.send (self.send_buffer)
else:
     # convert to ansi before sending
     sent = self.sock.send (bytes (self.send_buffer, "utf-8"))

This does not seem to be well accepted by the remote terminals, which simply display the special characters corresponding to the command and do not execute them.

Do I miss something?

Greetings

import os
from miniboa import TelnetServer
from time import sleep

server = TelnetServer()
clients = []

def on_connect(client):
    client.request_terminal_type()
    client.send("Hello, my friend. Stay awhile and listen.")
    clients.append(client)
    


def on_disconnect(client):
    clients.remove(client)


def check_client():
    for client in clients:
        if client.active:
            print(client.terminal_type)
            



server = TelnetServer(
    port=3333,
    address='',
    on_connect=on_connect,
    on_disconnect=on_disconnect)

while True:
    server.poll()
    check_client()

Text wrapping method

I have noticed that you do not use native Python wrapping function in
xterm.py. Is there any specific reason?

It's just a suggestion but You could do something similar to:

        content = file.read() #suppose that text is read from file
        paragraph_list = content.split("\n") #split it to paragraphs
        content_list = []
        for paragraph in paragraph_list:
            if not paragraph: #to handle empty new lines
                content_list1.append(" ")
            else:
                content_list.extend(textwrap.wrap(paragraph)) #split
paragraphs and put them again to the list
        wrapped_content = "\n\r".join(content_list1) #make string back but
with new line endings

Original issue reported on code.google.com by [email protected] on 5 Feb 2010 at 3:05

Release change with `client_class`???

I thought this was released, but apparently not :(

$ pip freeze | grep miniboa
miniboa==1.0.2
TypeError: __init__() got an unexpected keyword argument 'client_class'

Anyway we can get a release 1.0.3 :)

Telnet removes diacritical characters

In function
def _recv_byte(self, byte):
in telnet module, there is such condition:
## Filter out non-printing characters
if (byte >= ' ' and byte <= '~') or byte == '\n':

Unfortunately this removes not only non-printing characters but also
characters specific for different languages. 
In polish language there are 3 possibilities: iso, win and utf. 
So I decided to switch off this checking but I am not sure if or how it
could harm mud.
Other way would be to provide codes for all diacritical characters but if
mud allows to different languages it could be difficult.

Original issue reported on code.google.com by [email protected] on 22 Dec 2009 at 12:28

Create an acceptance test for Travis

Not entirely sure what the best approach is. Ultimately we just want a final acceptance test that:

  1. Starts a TelnetServer
  2. Create a sock to connect to it
  3. sock.send some message to the server
  4. Assert that the message was received and is == "whatever we sent"

Crash on some inputs [Python 3.5.2]

Hello,

I've been working on a game using miniboa as the base, and have discovered it gets crashy when it encounters inputs that (assumedly?) cp1252 does not know how to deal with:

Traceback (most recent call last):
  File "urmud.py", line 86, in <module>
    game.mainLoop(gameServer)
  File "/home/x/Documents/Development/python/urmud/working/game.py", line 341, in mainLoop
    pollServer(gameServer)
  File "/home/x/Documents/Development/python/urmud/working/game.py", line 319, in pollServer
    server.poll()
  File "/home/x/Documents/Development/python/urmud/working/miniboa/async.py", line 188, in poll
    self.clients[sock_fileno].socket_recv()
  File "/home/x/Documents/Development/python/urmud/working/miniboa/telnet.py", line 292, in socket_recv
    data = str(self.sock.recv(2048), "cp1252")
  File "/usr/lib/python3.5/encodings/cp1252.py", line 15, in decode
    return codecs.charmap_decode(input,errors,decoding_table)
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 1: character maps to <undefined>

So far I've discovered this works with ⁒ (u2052) and ⁄ (u2044), but considering the sheer size of unicode I'm just assuming there are more.

I'm actually using this to learn Python and I'm not really sure what the best way to handle this would be, so I figured I'd point it in the direction of the professionals.

And I did test it with the example chat_demo.py to be sure it wasn't something I broke. I was quite surprised to discover that it was not. :)

utf8, python3

i don't know if this is still being worked on or not, but if it is:

i started on grapevine support for my game that is using this, and part of that was switching the server encoding to utf8... and that caused all sorts of havoc, garbage chars everywhere

while trying to figure this out, i found this:

Python 3.8.3 (default, May 17 2020, 14:48:56) [GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> test = chr(201) #gmcp
>>> bytes(test, "cp1252")
b'\xc9'
>>> bytes(test, "utf8")
b'\xc3\x89'
>>> 

it looks to me like in utf8 the control character is no longer a valid oob control character, so the client of course just displays it... but i don't know if i'm just reading that wrong, as python (and character encoding especially) is not exactly my most knowledgeable area... for all i know the above is perfectly normal and i'm chasing the wrong thing here

anyways, whatever the case: the issue is that utf8 support with this server appears to be somewhat broken and i hope someone smarter than i knows how to fix it

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.