Adding a periodic IMC2 keepalive event. Other IMC2-connected games are now aware of our presence via the keepalive. Woot.
This commit is contained in:
parent
a7e89c1e54
commit
191f49ff4c
5 changed files with 106 additions and 9 deletions
|
|
@ -21,4 +21,15 @@ def cmd_imctest(command):
|
||||||
packet = IMC2PacketWhois(source_object, 'Cratylus')
|
packet = IMC2PacketWhois(source_object, 'Cratylus')
|
||||||
imc2_conn.IMC2_PROTOCOL_INSTANCE.send_packet(packet)
|
imc2_conn.IMC2_PROTOCOL_INSTANCE.send_packet(packet)
|
||||||
source_object.emit_to("Sent")
|
source_object.emit_to("Sent")
|
||||||
GLOBAL_CMD_TABLE.add_command("imctest", cmd_imctest)
|
GLOBAL_CMD_TABLE.add_command("imctest", cmd_imctest)
|
||||||
|
|
||||||
|
def cmd_imckeepalive(command):
|
||||||
|
"""
|
||||||
|
Shows a player's inventory.
|
||||||
|
"""
|
||||||
|
source_object = command.source_object
|
||||||
|
source_object.emit_to("Sending")
|
||||||
|
packet = IMC2PacketIsAlive()
|
||||||
|
imc2_conn.IMC2_PROTOCOL_INSTANCE.send_packet(packet)
|
||||||
|
source_object.emit_to("Sent")
|
||||||
|
GLOBAL_CMD_TABLE.add_command("imckeepalive", cmd_imckeepalive)
|
||||||
|
|
@ -25,6 +25,7 @@ class IMC2Protocol(StatefulTelnetProtocol):
|
||||||
IMC2_PROTOCOL_INSTANCE = self
|
IMC2_PROTOCOL_INSTANCE = self
|
||||||
self.is_authenticated = False
|
self.is_authenticated = False
|
||||||
self.auth_type = None
|
self.auth_type = None
|
||||||
|
self.server_name = None
|
||||||
self.network_name = None
|
self.network_name = None
|
||||||
self.sequence = None
|
self.sequence = None
|
||||||
|
|
||||||
|
|
@ -61,9 +62,10 @@ class IMC2Protocol(StatefulTelnetProtocol):
|
||||||
"""
|
"""
|
||||||
if line[:2] == "PW":
|
if line[:2] == "PW":
|
||||||
line_split = line.split(' ')
|
line_split = line.split(' ')
|
||||||
|
self.server_name = line_split[1]
|
||||||
self.network_name = line_split[4]
|
self.network_name = line_split[4]
|
||||||
self.is_authenticated = True
|
self.is_authenticated = True
|
||||||
self.sequence = time.time()
|
self.sequence = int(time.time())
|
||||||
print "IMC2: Successfully authenticated to the '%s' network." % self.network_name
|
print "IMC2: Successfully authenticated to the '%s' network." % self.network_name
|
||||||
|
|
||||||
def lineReceived(self, line):
|
def lineReceived(self, line):
|
||||||
|
|
|
||||||
33
src/imc2/events.py
Normal file
33
src/imc2/events.py
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
"""
|
||||||
|
This module contains all IMC2 events that are triggered periodically.
|
||||||
|
Most of these are used to maintain the existing connection and keep various
|
||||||
|
lists/caches up to date.
|
||||||
|
"""
|
||||||
|
from src import events
|
||||||
|
from src import scheduler
|
||||||
|
from src.imc2 import connection as imc2_conn
|
||||||
|
from src.imc2.packets import *
|
||||||
|
|
||||||
|
class IEvt_IMC2_KeepAlive(events.IntervalEvent):
|
||||||
|
"""
|
||||||
|
Event: Send periodic keepalives to network neighbors. This lets the other
|
||||||
|
games know that our game is still up and connected to the network. Also
|
||||||
|
provides some useful information about the client game.
|
||||||
|
"""
|
||||||
|
name = 'IEvt_IMC2_KeepAlive'
|
||||||
|
# Send keep-alive packets every 15 minutes.
|
||||||
|
interval = 900
|
||||||
|
description = "Send an IMC2 keepalive packet."
|
||||||
|
|
||||||
|
def event_function(self):
|
||||||
|
"""
|
||||||
|
This is the function that is fired every self.interval seconds.
|
||||||
|
"""
|
||||||
|
packet = IMC2PacketIsAlive()
|
||||||
|
imc2_conn.IMC2_PROTOCOL_INSTANCE.send_packet(packet)
|
||||||
|
|
||||||
|
def add_events():
|
||||||
|
"""
|
||||||
|
Adds the IMC2 events to the scheduler.
|
||||||
|
"""
|
||||||
|
scheduler.add_event(IEvt_IMC2_KeepAlive())
|
||||||
|
|
@ -19,7 +19,7 @@ class IMC2Packet(object):
|
||||||
target = None
|
target = None
|
||||||
destination = None
|
destination = None
|
||||||
# Optional data.
|
# Optional data.
|
||||||
optional_data = {}
|
optional_data = []
|
||||||
# Reference to the IMC2Protocol object doing the sending.
|
# Reference to the IMC2Protocol object doing the sending.
|
||||||
imc2_protocol = None
|
imc2_protocol = None
|
||||||
|
|
||||||
|
|
@ -29,8 +29,8 @@ class IMC2Packet(object):
|
||||||
"""
|
"""
|
||||||
if self.optional_data:
|
if self.optional_data:
|
||||||
data_string = ''
|
data_string = ''
|
||||||
for key, value in self.optional_data.items():
|
for value in self.optional_data:
|
||||||
self.data_string += '%s=%s ' % (key, value)
|
data_string += '%s=%s ' % (value[0], value[1])
|
||||||
return data_string.strip()
|
return data_string.strip()
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
@ -39,13 +39,18 @@ class IMC2Packet(object):
|
||||||
"""
|
"""
|
||||||
Calculates the sender name to be sent with the packet.
|
Calculates the sender name to be sent with the packet.
|
||||||
"""
|
"""
|
||||||
if self.sender:
|
if self.sender == '*':
|
||||||
|
# Some packets have no sender.
|
||||||
|
return '*'
|
||||||
|
elif self.sender:
|
||||||
|
# Player object.
|
||||||
name = self.sender.get_name(fullname=False, show_dbref=False,
|
name = self.sender.get_name(fullname=False, show_dbref=False,
|
||||||
show_flags=False,
|
show_flags=False,
|
||||||
no_ansi=True)
|
no_ansi=True)
|
||||||
# IMC2 does not allow for spaces.
|
# IMC2 does not allow for spaces.
|
||||||
return name.strip().replace(' ', '_')
|
return name.strip().replace(' ', '_')
|
||||||
else:
|
else:
|
||||||
|
# None value. Do something or other.
|
||||||
return 'Unknown'
|
return 'Unknown'
|
||||||
|
|
||||||
def assemble(self):
|
def assemble(self):
|
||||||
|
|
@ -80,7 +85,51 @@ class IMC2PacketWhois(IMC2Packet):
|
||||||
self.packet_type = 'whois'
|
self.packet_type = 'whois'
|
||||||
self.target = whois_target
|
self.target = whois_target
|
||||||
self.destination = '*'
|
self.destination = '*'
|
||||||
self.data = {'level': '5'}
|
self.optional_data = [('level', '5')]
|
||||||
|
|
||||||
|
class IMC2PacketIsAlive(IMC2Packet):
|
||||||
|
"""
|
||||||
|
Description:
|
||||||
|
This packet is the reply to a keepalive-request packet. It is responsible
|
||||||
|
for filling a client's mudlist with the information about other MUDs on the
|
||||||
|
network.
|
||||||
|
|
||||||
|
Data:
|
||||||
|
versionid=<string>
|
||||||
|
Where <string> is the text version ID of the client. ("IMC2 4.5 MUD-Net")
|
||||||
|
|
||||||
|
url=<string>
|
||||||
|
Where <string> is the proper URL of the client. (http://www.domain.com)
|
||||||
|
|
||||||
|
host=<string>
|
||||||
|
Where <string> is the telnet address of the MUD. (telnet://domain.com)
|
||||||
|
|
||||||
|
port=<int>
|
||||||
|
Where <int> is the telnet port of the MUD.
|
||||||
|
|
||||||
|
(These data fields are not sent by the MUD, they are added by the server.)
|
||||||
|
networkname=<string>
|
||||||
|
Where <string> is the network name that the MUD/server is on. ("MyNetwork")
|
||||||
|
|
||||||
|
sha256=<int>
|
||||||
|
This is an optional tag that denotes the SHA-256 capabilities of a
|
||||||
|
MUD or server.
|
||||||
|
|
||||||
|
Example of a received is-alive:
|
||||||
|
*@SomeMUD 1234567890 SomeMUD!Hub2 is-alive *@YourMUD versionid="IMC2 4.5 MUD-Net" url="http://www.domain.com" networkname="MyNetwork" sha256=1 host=domain.com port=5500
|
||||||
|
|
||||||
|
Example of a sent is-alive:
|
||||||
|
*@YourMUD 1234567890 YourMUD is-alive *@* versionid="IMC2 4.5 MUD-Net" url="http://www.domain.com" host=domain.com port=5500
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.sender = '*'
|
||||||
|
self.packet_type = 'is-alive'
|
||||||
|
self.target = '*'
|
||||||
|
self.destination = '*'
|
||||||
|
self.optional_data = [('versionid', '"Evennia IMC2"'),
|
||||||
|
('url', '"http://evennia.com"'),
|
||||||
|
('host', 'test.com'),
|
||||||
|
('port', '5555')]
|
||||||
|
|
||||||
class IMC2PacketAuthPlaintext(object):
|
class IMC2PacketAuthPlaintext(object):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ from django.db import connection
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from src.config.models import ConfigValue
|
from src.config.models import ConfigValue
|
||||||
from src.session import SessionProtocol
|
from src.session import SessionProtocol
|
||||||
from src.imc2.connection import IMC2ClientFactory
|
|
||||||
from src import events
|
from src import events
|
||||||
from src import logger
|
from src import logger
|
||||||
from src import session_mgr
|
from src import session_mgr
|
||||||
|
|
@ -146,9 +145,12 @@ for port in settings.GAMEPORTS:
|
||||||
|
|
||||||
|
|
||||||
if settings.IMC2_ENABLED:
|
if settings.IMC2_ENABLED:
|
||||||
|
from src.imc2.connection import IMC2ClientFactory
|
||||||
|
from src.imc2 import events as imc2_events
|
||||||
imc2_factory = IMC2ClientFactory()
|
imc2_factory = IMC2ClientFactory()
|
||||||
svc = internet.TCPClient(settings.IMC2_SERVER_ADDRESS,
|
svc = internet.TCPClient(settings.IMC2_SERVER_ADDRESS,
|
||||||
settings.IMC2_SERVER_PORT,
|
settings.IMC2_SERVER_PORT,
|
||||||
imc2_factory)
|
imc2_factory)
|
||||||
svc.setName('IMC2')
|
svc.setName('IMC2')
|
||||||
svc.setServiceParent(serviceCollection)
|
svc.setServiceParent(serviceCollection)
|
||||||
|
imc2_events.add_events()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue