Compare commits

..

85 Commits

Author SHA1 Message Date
SpudGunMan
d425298cd9 Update dopewar.py 2024-09-28 12:17:16 -07:00
SpudGunMan
786815d073 Update dopewar.py 2024-09-28 12:04:17 -07:00
SpudGunMan
54cad92a3f enhance 💊 game display 2024-09-28 12:03:08 -07:00
SpudGunMan
54e21f4644 Update mesh_bot.py 2024-09-28 00:53:19 -07:00
SpudGunMan
3c76f177cd Update simulator.py 2024-09-28 00:46:47 -07:00
SpudGunMan
aa05c62d94 fix🍋hs 2024-09-28 00:45:57 -07:00
SpudGunMan
3f16158e27 Update mesh_bot.py 2024-09-28 00:28:59 -07:00
SpudGunMan
6f2824512d highscoreEnhance 2024-09-28 00:27:45 -07:00
SpudGunMan
723b67f886 🥔 2024-09-28 00:14:27 -07:00
SpudGunMan
008d55e63b Update mesh_bot.py 2024-09-28 00:12:33 -07:00
SpudGunMan
79885454ab fixLongStandingIssues
fix long time bugs of 21 and the suggestions
2024-09-27 23:47:14 -07:00
SpudGunMan
ba21723bdc fix BlackJackwin! 2024-09-27 23:38:40 -07:00
SpudGunMan
c36c4918a8 Update mesh_bot.py 2024-09-27 22:33:07 -07:00
SpudGunMan
853147518d space 2024-09-27 22:32:46 -07:00
SpudGunMan
2f19d86c95 💩
: get it
2024-09-27 22:17:07 -07:00
SpudGunMan
39bdabffcb Update blackjack.py 2024-09-27 21:57:40 -07:00
SpudGunMan
a7bdaedfe1 Update blackjack.py 2024-09-27 21:57:22 -07:00
SpudGunMan
1c6106081f Weight2Wait
add weight to the wait for responses. as the comment says this is a specific use case for the Q: blah blah A: 2. I am seeing a hang up this is to help keep delivery high.
2024-09-27 21:48:13 -07:00
SpudGunMan
8ab6cded2e 🥝 2024-09-27 21:14:06 -07:00
SpudGunMan
ff63bb959a Update mesh_bot.py 2024-09-27 20:55:50 -07:00
SpudGunMan
6c79bb1ff0 Update mesh_bot.py 2024-09-27 20:50:36 -07:00
SpudGunMan
ce73336c0c Update mesh_bot.py 2024-09-27 20:49:05 -07:00
SpudGunMan
248977c5b5 enhance
* replay hand with H or R
2024-09-27 18:06:11 -07:00
SpudGunMan
77a6e63210 howRandom 2024-09-27 17:39:55 -07:00
SpudGunMan
6f6fb35177 IgnoreDefaultChannel
ability to fully ignore the default channel if wanted, default is false
2024-09-27 17:37:34 -07:00
SpudGunMan
9db565cb4f changeLogPath
tidy up this mess
2024-09-27 17:18:35 -07:00
SpudGunMan
2a254a7fab fixNewTable.pkl 2024-09-27 01:06:15 -07:00
SpudGunMan
15e76ab029 fixCasinoGamesForGood? 2024-09-27 00:57:57 -07:00
SpudGunMan
66b95cdaa0 casinoHighScores
I got a really good score its a shame it was wasted
2024-09-27 00:25:17 -07:00
SpudGunMan
32ea93cb88 Update mesh_bot.py 2024-09-26 22:11:42 -07:00
SpudGunMan
22a2a64861 Update bbstools.py 2024-09-26 21:08:29 -07:00
SpudGunMan
d841fdf02c bbsinfo 2024-09-26 21:03:57 -07:00
Kelly
9421f09ded Merge pull request #69 from SpudGunMan/lab
messages from !hex ID
2024-09-26 20:56:35 -07:00
SpudGunMan
b4af552fb9 Update mesh_bot.py 2024-09-26 20:55:32 -07:00
Kelly
69dfb17460 Merge pull request #68 from Nestpebble/main
Add in BBS-DM via node hex ID
2024-09-26 20:47:09 -07:00
SpudGunMan
4703750c27 Update videopoker.py 2024-09-26 20:45:49 -07:00
Nestpebble
40caf99939 Merge branch 'SpudGunMan:main' into main 2024-09-27 03:43:45 +01:00
Nestpebble
df5f648b26 try and round off adding an interpreter to the bbs DM 2024-09-27 03:30:21 +01:00
Nestpebble
55472bbbc0 try this 2024-09-27 03:12:40 +01:00
Nestpebble
f23c4e2b6a sdf 2024-09-27 02:29:58 +01:00
Nestpebble
0b101d662e trying to simplify nodeid entry... 2024-09-27 02:26:55 +01:00
SpudGunMan
a7f07afc14 consolidateTime 2024-09-26 18:13:58 -07:00
SpudGunMan
2715021898 Update README.md 2024-09-26 18:02:52 -07:00
SpudGunMan
e8fa0036e2 Update mesh_bot.py 2024-09-26 17:57:05 -07:00
SpudGunMan
f628a5e7ef Update mesh_bot.py 2024-09-26 17:56:56 -07:00
SpudGunMan
95e6bc120e Update mesh_bot.py 2024-09-26 17:32:34 -07:00
SpudGunMan
0e35c891c4 Update mesh_bot.py 2024-09-26 17:29:54 -07:00
SpudGunMan
b7a3e7014c Update mesh_bot.py 2024-09-26 17:26:42 -07:00
Nestpebble
0c1c587bc7 strip ! from tonode, cos its copied by default on
the android app.
2024-09-27 01:26:01 +01:00
SpudGunMan
a0a2c60e63 Update mesh_bot.py 2024-09-26 17:25:29 -07:00
SpudGunMan
45c912a0d6 Update mesh_bot.py 2024-09-26 17:19:50 -07:00
Kelly
39945f161d Merge pull request #66 from Nestpebble/main
Help messages, condensed ping
2024-09-26 17:15:46 -07:00
Nestpebble
ed958302bd sdfsdfsdf 2024-09-26 23:07:19 +01:00
Nestpebble
477f2141d7 sdfsdf 2024-09-26 22:57:20 +01:00
Nestpebble
d321a958f0 more tidying 2024-09-26 22:50:45 +01:00
Nestpebble
d14f1df823 tweak some help messages 2024-09-26 22:49:20 +01:00
Nestpebble
f7e3b9f6c7 Merge branch 'SpudGunMan:main' into main 2024-09-26 22:25:20 +01:00
Nestpebble
cd3ac201f8 general tidy up, done 2024-09-26 22:23:15 +01:00
Nestpebble
ceef493b01 dfgdf 2024-09-26 22:17:38 +01:00
Nestpebble
480a75e30c Merge branch 'main' of https://github.com/Nestpebble/meshing-around 2024-09-26 22:17:02 +01:00
Nestpebble
d8cc953fe7 Removed handle_testing & handle_ack,
now in handle_ping
2024-09-26 22:16:17 +01:00
Nestpebble
0baec88321 Removed handle_testing & handle_ack,
now in handle_ping
2024-09-26 22:12:10 +01:00
Nestpebble
74bd3f681f dssdf 2024-09-26 22:05:31 +01:00
Nestpebble
713b750f4a sdfsd 2024-09-26 21:56:41 +01:00
Nestpebble
11eee911ca sdfsdf 2024-09-26 21:54:47 +01:00
Nestpebble
b288aaea90 szadsad 2024-09-26 21:32:25 +01:00
Nestpebble
7acc018fd2 sdfsd 2024-09-26 21:30:35 +01:00
Nestpebble
7aba1096f9 szd 2024-09-26 21:20:30 +01:00
Nestpebble
0be7202144 dsfrg 2024-09-26 21:18:49 +01:00
Nestpebble
83a5db74e5 Merge branch 'main' of https://github.com/Nestpebble/meshing-around 2024-09-26 21:16:20 +01:00
Nestpebble
8dc4371beb deghdfgdrfgdf 2024-09-26 21:16:08 +01:00
Nestpebble
e5045a0984 drfgdf 2024-09-26 21:14:29 +01:00
Nestpebble
2c9b37a0cc sdfsdfsdf 2024-09-26 21:09:53 +01:00
Nestpebble
b608482220 typo 2024-09-26 21:05:11 +01:00
Nestpebble
9290fac899 I think I consolidated the pings... 2024-09-26 21:03:43 +01:00
Nestpebble
d7901ee575 sdfsdfsd 2024-09-26 18:57:55 +01:00
Nestpebble
7eb33a5aef sdfsdfsdf 2024-09-26 18:56:36 +01:00
Nestpebble
c5dc103ac0 compressed ping response 2024-09-26 15:28:48 +01:00
Nestpebble
c90172a862 fixed it 2024-09-26 14:31:58 +01:00
Nestpebble
8540786c2c added help text to history 2024-09-26 14:28:49 +01:00
Nestpebble
7aeb8e851d Update mesh_bot.py 2024-09-26 14:24:27 +01:00
Nestpebble
2f207dc3d9 Update mesh_bot.py 2024-09-26 14:18:25 +01:00
Nestpebble
7e2be73962 Update mesh_bot.py 2024-09-26 14:17:29 +01:00
SpudGunMan
e2a87eb945 ReticulatingSplines
Reticulating some Splines and other items which need full Reticulation.
2024-09-26 00:18:07 -07:00
Nestpebble
f6215d3563 Tidied up, added a few help messages. 2024-09-26 02:02:26 +01:00
14 changed files with 382 additions and 292 deletions

View File

@@ -34,6 +34,7 @@ Any messages that are over 160 characters are chunked into 160 message bytes to
- `bbsread` read a message example use: `bbsread #1`
- `bbspost` post a message to public board or send a DM example use: `bbspost $subject #message, or bbspost @nodeNumber #message or bbspost @nodeShortName #message`
- `bbsdelete` delete a message example use: `bbsdelete #4`
- `bbsinfo` Stats on BBS delivery and messages (sysop)
- Other functions
- `whereami` returns the address of location of sender if known
- `whoami` returns some details of the node asking
@@ -48,11 +49,11 @@ Any messages that are over 160 characters are chunked into 160 message bytes to
- `lheard` returns the last 5 heard nodes with SNR, can also use `sitrep`
- `history` returns the last commands ran by user(s)
- `cmd` returns the list of commands (the help message)
- Games
- `lemonstand` plays the classic Lemonade Stand Finance game via DM
- `dopewars` plays the classic drug trader game via DM
- `blackjack` BlackJack
- `videopoker` Video Poker
- Games - via DM
- `lemonstand` plays the classic Lemonade Stand Finance
- `dopewars` plays the classic drug trader
- `blackjack` BlackJack, Casino 21
- `videopoker` Video Poker, basic 5 card hold
## pong_bot.sh
Stripped-down bot, mostly around for archive purposes. The mesh-bot enhanced modules can be disabled by config to disable features.
@@ -192,20 +193,6 @@ googleSearchResults = 3 # number of google search results to include in the cont
llm_history_limit = 6 # limit the history to 3 messages (come in pairs) more results = more compute time
```
Logging messages to disk or Syslog to disk uses the python native logging function. Take a look at the [/modules/log.py](/modules/log.py) you can set the file logger for syslog to INFO for example to not log DEBUG messages to file log, or modify the stdOut level.
```
[general]
# logging to file of the non Bot messages
LogMessagesToFile = True
# Logging of system messages to file
SyslogToFile = True
```
Example to log to disk only INFO and higher (ignore DEBUG)
```
*log.py
file_handler.setLevel(logging.INFO) # DEBUG used by default for system logs to disk example here shows INFO
```
The Scheduler is enabled in the [settings.py](modules/settings.py) by setting `scheduler_enabled = True` the actions and settings are via code only at this time. see [mesh_bot.py](mesh_bot.py) around line [425](https://github.com/SpudGunMan/meshing-around/blob/22983133ee4db3df34f66699f565e506de296197/mesh_bot.py#L425-L435) to edit schedule its most flexible to edit raw code right now. See https://schedule.readthedocs.io/en/stable/ for more.
```

View File

@@ -25,8 +25,10 @@ port = /dev/ttyUSB0
[general]
# if False will respond on all channels but the default channel
respond_by_dm_only = True
# defaultChannel is the meshtastic default public channel
# defaultChannel is the meshtastic default public channel, e.g. LongFast
defaultChannel = 0
# ignoreDefaultChannel, the bot will ignore the default channel set above
ignoreDefaultChannel = False
# motd is reset to this value on boot
motd = Thanks for using MeshBOT! Have a good day!
welcome_message = MeshBot, here for you like a friend who is not. Try sending: ping @foo or, cmd

View File

@@ -11,7 +11,7 @@ except Exception as e:
with open('bbsdb.pkl', 'rb') as f:
bbs_messages = pickle.load(f)
except Exception as e:
print ("\nSystem: bbsdb.pkl not found")
bbs_messages = "System: bbsdb.pkl not found"
try:
with open('../bbsdm.pkl', 'rb') as f:
@@ -21,7 +21,7 @@ except Exception as e:
with open('bbsdm.pkl', 'rb') as f:
bbs_dm = pickle.load(f)
except Exception as e:
print ("\nSystem: bbsdm.pkl not found")
bbs_dm = "System: bbsdm.pkl not found"
# Game HS tables
try:
@@ -32,7 +32,7 @@ except Exception as e:
with open('lemonade_hs.pkl', 'rb') as f:
lemon_score = pickle.load(f)
except Exception as e:
print ("\nSystem: lemonade_hs.pkl not found")
lemon_score = "System: lemonade_hs.pkl not found"
try:
with open('../dopewar_hs.pkl', 'rb') as f:
@@ -42,13 +42,36 @@ except Exception as e:
with open('dopewar_hs.pkl', 'rb') as f:
dopewar_score = pickle.load(f)
except Exception as e:
print ("\nSystem: dopewar_hs.pkl not found")
dopewar_score = "System: dopewar_hs.pkl not found"
try:
with open('../blackjack_hs.pkl', 'rb') as f:
blackjack_score = pickle.load(f)
except Exception as e:
try:
with open('blackjack_hs.pkl', 'rb') as f:
blackjack_score = pickle.load(f)
except Exception as e:
blackjack_score = "System: blackjack_hs.pkl not found"
print ("\nSystem: bbs_messages")
try:
with open('../videopoker_hs.pkl', 'rb') as f:
videopoker_score = pickle.load(f)
except Exception as e:
try:
with open('videopoker_hs.pkl', 'rb') as f:
videopoker_score = pickle.load(f)
except Exception as e:
videopoker_score = "System: videopoker_hs.pkl not found"
print ("\n Meshing-Around Database Admin Tool\n")
print ("System: bbs_messages")
print (bbs_messages)
print ("\nSystem: bbs_dm")
print (bbs_dm)
print ("Game HS tables")
print (f"\n\nGame HS tables\n")
print (f"lemon:{lemon_score}")
print (f"dopewar:{dopewar_score}")
print (f"dopewar:{dopewar_score}")
print (f"blackjack:{blackjack_score}")
print (f"videopoker:{videopoker_score}")
print ("\n")

View File

@@ -8,6 +8,7 @@ import random
projectName = "example_handler" # name of _handler function to match the function name under test
randomNode = False # Set to True to use random node IDs
# bot.py Simulated functions
def get_NodeID():
nodeList = [4258675309, 1212121212, 1234567890, 9876543210]
if randomNode:
@@ -15,6 +16,10 @@ def get_NodeID():
else:
nodeID = nodeList[0]
return nodeID
def get_name_from_number(nodeID, length='short', interface=1):
# return random name for nodeID
names = ["Max","Molly","Jake"]
return names[random.randint(0, len(names)-1)]
# # end Initialization of the tool
# # Function to handle, or the project in test

15
logs/README.md Normal file
View File

@@ -0,0 +1,15 @@
Logs will collect here.
Logging messages to disk or Syslog to disk uses the python native logging function. Take a look at the [/modules/log.py](/modules/log.py) you can set the file logger for syslog to INFO for example to not log DEBUG messages to file log, or modify the stdOut level.
```
[general]
# logging to file of the non Bot messages
LogMessagesToFile = True
# Logging of system messages to file
SyslogToFile = True
```
Example to log to disk only INFO and higher (ignore DEBUG)
```
*log.py
file_handler.setLevel(logging.INFO) # DEBUG used by default for system logs to disk example here shows INFO
```

View File

@@ -4,6 +4,7 @@
import asyncio
import time # for sleep, get some when you can :)
import random
from pubsub import pub # pip install pubsub
from modules.log import *
from modules.system import *
@@ -24,15 +25,16 @@ def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_n
# Command List
default_commands = {
"ping": lambda: handle_ping(message, hop, snr, rssi),
"ping": lambda: handle_ping(message, hop, snr, rssi, isDM),
"pong": lambda: "🏓PING!!",
"motd": lambda: handle_motd(message, message_from_id),
"motd": lambda: handle_motd(message, message_from_id, isDM),
"bbshelp": bbs_help,
"wxalert": lambda: handle_wxalert(message_from_id, deviceID, message),
"wxa": lambda: handle_wxalert(message_from_id, deviceID, message),
"wxc": lambda: handle_wxc(message_from_id, deviceID, 'wxc'),
"wx": lambda: handle_wxc(message_from_id, deviceID, 'wx'),
"wiki:": lambda: handle_wiki(message),
"wiki:": lambda: handle_wiki(message, isDM),
"wiki?": lambda: handle_wiki(message, isDM),
"games": lambda: gamesCmdList,
"dopewars": lambda: handleDopeWars(message_from_id, message, deviceID),
"lemonstand": lambda: handleLemonade(message_from_id, message),
@@ -46,21 +48,22 @@ def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_n
"bbspost": lambda: handle_bbspost(message, message_from_id, deviceID),
"bbsread": lambda: handle_bbsread(message),
"bbsdelete": lambda: handle_bbsdelete(message, message_from_id),
"messages": lambda: handle_messages(deviceID, channel_number, msg_history, publicChannel),
"bbsinfo": lambda: get_bbs_stats(),
"messages": lambda: handle_messages(message, deviceID, channel_number, msg_history, publicChannel, isDM),
"cmd": lambda: help_message,
"history": lambda: handle_history(message_from_id, deviceID),
"history": lambda: handle_history(message, message_from_id, deviceID, isDM),
"sun": lambda: handle_sun(message_from_id, deviceID, channel_number),
"hfcond": hf_band_conditions,
"solar": lambda: drap_xray_conditions() + "\n" + solar_conditions(),
"lheard": lambda: handle_lheard(message_from_id, deviceID),
"sitrep": lambda: handle_lheard(message_from_id, deviceID),
"lheard": lambda: handle_lheard(message, message_from_id, deviceID, isDM),
"sitrep": lambda: handle_lheard(message, message_from_id, deviceID, isDM),
"whereami": lambda: handle_whereami(message_from_id, deviceID, channel_number),
"tide": lambda: handle_tide(message_from_id, deviceID, channel_number),
"moon": lambda: handle_moon(message_from_id, deviceID, channel_number),
"ack": lambda: handle_ack(hop, snr, rssi),
"testing": lambda: handle_testing(message, hop, snr, rssi),
"test": lambda: handle_testing(message, hop, snr, rssi),
"whoami": lambda: handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus)
"ack": lambda: handle_ping(message, hop, snr, rssi, isDM),
"testing": lambda: handle_ping(message, hop, snr, rssi, isDM),
"test": lambda: handle_ping(message, hop, snr, rssi, isDM),
"whoami": lambda: handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus),
}
# set the command handler
@@ -97,24 +100,37 @@ def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_n
return bot_response
def handle_ping(message, hop, snr, rssi):
if "@" in message:
if hop == "Direct":
return "🏓PONG, " + f"SNR:{snr} RSSI:{rssi}" + " at: " + message.split("@")[1]
else:
return "🏓PONG, " + hop + " at: " + message.split("@")[1]
elif "#" in message:
if hop == "Direct":
return "🏓PONG, " + f"SNR:{snr} RSSI:{rssi}" + " #" + message.split("#")[1]
else:
return "🏓PONG, " + hop + " #" + message.split("#")[1]
else:
if hop == "Direct":
return "🏓PONG, " + f"SNR:{snr} RSSI:{rssi}"
else:
return "🏓PONG, " + hop
def handle_ping(message, hop, snr, rssi, isDM):
if "?" in message and isDM:
return message.split("?")[0].title() + " command returns SNR and RSSI, or hopcount from your message. Try adding e.g. @place or #tag"
msg = ""
def handle_motd(message, message_from_id):
if "ping" in message.lower():
msg = "🏓PONG, "
elif "test" in message.lower() or "testing" in message.lower():
msg = random.choice(["🎙Testing 1,2,3\n", "🎙Testing, ",\
"🎙Testing, testing, ",\
"🎙Ah-wun, ah-two... ", "🎙Is this thing on? ",\
"🎙Roger that! ",])
elif "ack" in message.lower():
msg = random.choice(["✋ACK-ACK!\n", "✋Ack to you!\n"])
else:
msg = ""
if hop == "Direct":
msg = msg + f"SNR:{snr} RSSI:{rssi}"
else:
msg = msg + hop
if "@" in message:
msg = msg + " @" + message.split("@")[1]
elif "#" in message:
msg = msg + " #" + message.split("#")[1]
return msg
def handle_motd(message, message_from_id, isDM):
global MOTD
isAdmin = False
msg = ""
@@ -127,17 +143,19 @@ def handle_motd(message, message_from_id):
else:
isAdmin = True
if "$" in message and isAdmin:
# admin help via DM
if "?" in message and isDM and isAdmin:
msg = "Message of the day, set with 'motd $ HelloWorld!'"
elif "?" in message and isDM and not isAdmin:
# non-admin help via DM
msg = "Message of the day"
elif "$" in message and isAdmin:
motd = message.split("$")[1]
MOTD = motd.rstrip()
logger.debug(f"System: {message_from_id} changed MOTD: {MOTD}")
msg = "MOTD changed to: " + MOTD
elif "?" in message:
msg = "Message of the day, set with 'motd $ HelloWorld!'"
else:
logger.debug(f"System: {message_from_id} requested MOTD: {MOTD} isAdmin: {isAdmin}")
msg = "MOTD: " + MOTD
return msg
def handle_wxalert(message_from_id, deviceID, message):
@@ -153,14 +171,16 @@ def handle_wxalert(message_from_id, deviceID, message):
return weatherAlert
def handle_wiki(message):
def handle_wiki(message, isDM):
# location = get_node_location(message_from_id, deviceID)
msg = "Wikipedia search function. \nUsage example:📲wiki: travelling gnome"
if "wiki:" in message.lower():
search = message.split(":")[1]
search = search.strip()
if search:
return get_wikipedia_summary(search)
return "Please add a search term example:wiki: travelling gnome"
return "Please add a search term example:📲wiki: travelling gnome"
return msg
# Runtime Variables for LLM
llmRunCounter = 0
@@ -268,10 +288,9 @@ def handleDopeWars(nodeID, message, rxNode):
# welcome new player
if not last_cmd:
msg = 'Welcome to 💊Dope Wars!💉 You have ' + str(total_days) + ' days to make as much 💰 as possible! '
msg = 'Welcome to 💊Dope Wars💉 You have ' + str(total_days) + ' days to make as much 💰 as possible! '
high_score = getHighScoreDw()
msg += 'The High Score is $' + "{:,}".format(high_score.get('cash')) + ' by user ' + get_name_from_number(high_score.get('userID') , 'short', rxNode)
msg += 'Game Played via Direct Message.' + f'.\n'
msg += 'The High Score is $' + "{:,}".format(high_score.get('cash')) + ' by user ' + get_name_from_number(high_score.get('userID') , 'short', rxNode) +'\n'
msg += playDopeWars(nodeID, message)
else:
logger.debug("System: DopeWars: last_cmd: " + str(last_cmd))
@@ -284,8 +303,16 @@ def handle_gTnW():
response = ["The only winning move is not to play.", "What are you doing, Dave?",\
"Greetings, Professor Falken.", "Shall we play a game?", "How about a nice game of chess?",\
"You are a hard man to reach. Could not find you in Seattle and no terminal is in operation at your classified address.",\
"I should reach Defcon 1 and release my missiles in 28 hours.","T-minus thirty","?SYNTAX return[ERROR 54]"]
return random.choice(response)
"I should reach Defcon 1 and release my missiles in 28 hours.","T-minus thirty","?SYNTAX return[ERROR 54]", "reticulating splines"]
length = len(response)
indices = list(range(length))
# Shuffle the indices using a convoluted method
for i in range(length):
swap_idx = (i * 3 + 7) % length
indices[i], indices[swap_idx] = indices[swap_idx], indices[i]
# Select a random response from the shuffled list. anyone enjoy the game, killerbunnies(.com)
selected_index = random.choice(indices)
return response[selected_index]
def handleLemonade(nodeID, message):
global lemonadeTracker, lemonadeCups, lemonadeLemons, lemonadeSugar, lemonadeWeeks, lemonadeScore, lemon_starting_cash, lemon_total_weeks
@@ -308,7 +335,17 @@ def handleLemonade(nodeID, message):
# create new player if not in tracker
if last_cmd == "":
create_player(nodeID)
msg += "Welcome to 🍋Lemonade Stand!🍋 Game Played via Direct Message."
msg += "Welcome🍋🥤"
# high score
highScore = {"userID": 0, "cash": 0, "success": 0}
highScore = getHighScoreLemon()
if highScore != 0:
if highScore['userID'] != 0:
nodeName = get_name_from_number(highScore['userID'])
if nodeName.isnumeric() and interface2_enabled:
nodeName = get_name_from_number(highScore['userID'], 'long', 2)
msg += f" HighScore🥇{nodeName} 💰{highScore['cash']}k "
msg += start_lemonade(nodeID=nodeID, message=message, celsius=False)
# wait a second to keep from message collision
@@ -328,43 +365,28 @@ def handleBlackJack(nodeID, message):
# if player sends a L for leave table
if message.lower().startswith("l"):
logger.debug(f"System: BlackJack: {nodeID} is leaving the table")
# add 16 hours to the player time to leave the table, this will be detected by bot logic as player leaving
msg = "You have left the table."
for i in range(len(jackTracker)):
if jackTracker[i]['nodeID'] == nodeID:
jackTracker[i]['time'] = time.time() - 57600
jackTracker[i]['cmd'] = "new"
jackTracker[i]['p_cards'] = []
jackTracker[i]['d_cards'] = []
jackTracker[i]['p_hand'] = []
jackTracker[i]['d_hand'] = []
jackTracker.pop(i)
return msg
# # Save the game state to pickle
# try:
# with open('blackjack_hs.pkl', 'wb') as file:
# pickle.dump(jackTracker, file)
# except FileNotFoundError:
# logger.debug("System: BlackJack: Creating new blackjack_hs.pkl file")
# with open('blackjack_hs.pkl', 'wb') as file:
# pickle.dump(jackTracker, file)
else:
# find higest dollar amount in tracker for high score
if last_cmd == "new":
high_score = 0
for i in range(len(jackTracker)):
if jackTracker[i]['cash'] > high_score:
high_score = int(jackTracker[i]['cash'])
user = jackTracker[i]['nodeID']
if user != 0:
msg += f" Ranking🥇:{get_name_from_number(user)} with {high_score} chips. "
else:
# Play BlackJack
msg = playBlackJack(nodeID=nodeID, message=message)
if last_cmd != "":
logger.debug(f"System: BlackJack: {nodeID} last command: {last_cmd}")
time.sleep(1)
else:
highScore = {'nodeID': 0, 'highScore': 0}
highScore = loadHSJack()
if highScore != 0:
if highScore['nodeID'] != 0:
nodeName = get_name_from_number(highScore['nodeID'])
if nodeName.isnumeric() and interface2_enabled:
nodeName = get_name_from_number(highScore['nodeID'], 'long', 2)
msg += f" HighScore🥇{nodeName} with {highScore['highScore']} chips. "
time.sleep(1.5) # short answers with long replies can cause message collision added wait
return msg
def handleVideoPoker(nodeID, message):
@@ -374,12 +396,10 @@ def handleVideoPoker(nodeID, message):
# if player sends a L for leave table
if message.lower().startswith("l"):
logger.debug(f"System: VideoPoker: {nodeID} is leaving the table")
# add 16 hours to the player time to leave the table, this will be detected by bot logic as player leaving
msg = "You have left the table."
for i in range(len(vpTracker)):
if vpTracker[i]['nodeID'] == nodeID:
vpTracker[i]['time'] = time.time() - 57600
vpTracker[i]['cmd'] = "new"
vpTracker.pop(i)
return msg
else:
# Play Video Poker
@@ -393,27 +413,18 @@ def handleVideoPoker(nodeID, message):
# find higest dollar amount in tracker for high score
if last_cmd == "new":
high_score = 0
user = 0
for i in range(len(vpTracker)):
if vpTracker[i]['highScore'] > high_score:
high_score = vpTracker[i]['highScore']
user = vpTracker[i]['nodeID']
if user != 0:
msg += f"\nHigh Score: {high_score} by {get_name_from_number(user)}"
# # Save the game high_score to pickle
# try:
# with open('videopoker_hs.pkl', 'wb') as file:
# pickle.dump(high_score, file)
# except FileNotFoundError:
# logger.debug("System: BlackJack: Creating new videopoker_hs.pkl file")
# with open('videopoker_hs.pkl', 'wb') as file:
# pickle.dump(high_score, file)
highScore = {'nodeID': 0, 'highScore': 0}
highScore = loadHSVp()
if highScore != 0:
if highScore['nodeID'] != 0:
nodeName = get_name_from_number(highScore['nodeID'])
if nodeName.isnumeric() and interface2_enabled:
nodeName = get_name_from_number(highScore['nodeID'], 'long', 2)
msg += f" HighScore🥇{nodeName} with {highScore['highScore']} coins. "
if last_cmd != "":
logger.debug(f"System: VideoPoker: {nodeID} last command: {last_cmd}")
time.sleep(1)
time.sleep(1.5) # short answers with long replies can cause message collision added wait
return msg
def handle_wxc(message_from_id, deviceID, cmd):
@@ -442,60 +453,75 @@ def handle_bbspost(message, message_from_id, deviceID):
logger.info(f"System: BBS Post: {subject} Body: {body}")
return bbs_post_message(subject, body, message_from_id)
elif not "example:" in message:
return "example: bbspost $subject #message"
return "example: bbspost $subject #✉️message"
elif "@" in message and not "example:" in message:
toNode = message.split("@")[1].split("#")[0]
toNode = toNode.rstrip()
if toNode.isalpha() or not toNode.isnumeric():
if toNode.startswith("!") and len(toNode) == 9:
# mesh !hex
try:
toNode = int(toNode.strip("!"),16)
except ValueError as e:
toNode = 0
elif toNode.isalpha() or not toNode.isnumeric():
# try short name
toNode = get_num_from_short_name(toNode, deviceID)
if "#" in message:
if toNode == 0:
return "Node not found " + message.split("@")[1].split("#")[0]
if "#" in message:
body = message.split("#")[1]
return bbs_post_dm(toNode, body, message_from_id)
else:
return "example: bbspost @nodeNumber/ShortName #message"
return "example: bbspost @nodeNumber/ShortName/!hex #✉️message"
elif not "example:" in message:
return "example: bbspost $subject #message, or bbspost @node #message"
return "example: bbspost $subject #✉️message, or bbspost @node #✉️message"
def handle_bbsread(message):
if "#" in message and not "example:" in message:
messageID = int(message.split("#")[1])
return bbs_read_message(messageID)
elif not "example:" in message:
return "Please add a message number example: bbsread #14"
return "Please add a ✉️message number example: bbsread #14"
def handle_bbsdelete(message, message_from_id):
if "#" in message and not "example:" in message:
messageID = int(message.split("#")[1])
return bbs_delete_message(messageID, message_from_id)
elif not "example:" in message:
return "Please add a message number example: bbsdelete #14"
return "Please add a ✉️message number example: bbsdelete #14"
def handle_messages(deviceID, channel_number, msg_history, publicChannel):
response = ""
for msgH in msg_history:
if msgH[4] == deviceID:
if msgH[2] == channel_number or msgH[2] == publicChannel:
response += f"\n{msgH[0]}: {msgH[1]}"
if len(response) > 0:
return "Message History:" + response
def handle_messages(message, deviceID, channel_number, msg_history, publicChannel, isDM):
if "?" in message and isDM:
return message.split("?")[0].title() + " command returns the last " + str(storeFlimit) + " messages sent on a channel."
else:
return "No messages in history"
response = ""
for msgH in msg_history:
if msgH[4] == deviceID:
if msgH[2] == channel_number or msgH[2] == publicChannel:
response += f"\n{msgH[0]}: {msgH[1]}"
if len(response) > 0:
return "Message History:" + response
else:
return "No messages in history"
def handle_sun(message_from_id, deviceID, channel_number):
location = get_node_location(message_from_id, deviceID, channel_number)
return get_sun(str(location[0]), str(location[1]))
def handle_lheard(nodeid, deviceID):
# display last heard nodes add to response
bot_response = str(get_node_list(1))
# gather telemetry
chutil1 = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("channelUtilization", 0), 1)
airUtilTx = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("airUtilTx", 0), 1)
uptimeSeconds = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("uptimeSeconds", 0)
batteryLevel = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("batteryLevel", 0)
voltage = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("voltage", 0)
def handle_lheard(message, nodeid, deviceID, isDM):
if "?" in message and isDM:
return message.split("?")[0].title() + " command returns a list of the nodes that have been heard recently"
else:
# display last heard nodes add to response
bot_response = str(get_node_list(1))
# gather telemetry
chutil1 = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("channelUtilization", 0), 1)
airUtilTx = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("airUtilTx", 0), 1)
uptimeSeconds = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("uptimeSeconds", 0)
batteryLevel = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("batteryLevel", 0)
voltage = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("voltage", 0)
if interface2_enabled:
bot_response += "P2:\n" + str(get_node_list(2))
chutil2 = round(interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("channelUtilization", 0), 1)
@@ -510,47 +536,35 @@ def handle_lheard(nodeid, deviceID):
if interface2_enabled:
bot_response += " P2:" + str(chutil2) + "%" + "/" + str(airUtilTx2) + "%"
# convert uptime to minutes, hours, or days
if uptimeSeconds > 0 or uptimeSeconds2 > 0:
uptimeSeconds = round(uptimeSeconds / 60)
uptimeSeconds2 = round(uptimeSeconds2 / 60)
designator = "m"
if uptimeSeconds > 60 or uptimeSeconds2 > 60:
uptimeSeconds = round(uptimeSeconds / 60)
uptimeSeconds2 = round(uptimeSeconds2 / 60)
designator = "h"
if uptimeSeconds > 24 or uptimeSeconds2 > 24:
uptimeSeconds = round(uptimeSeconds / 24)
uptimeSeconds2 = round(uptimeSeconds2 / 24)
designator = "d"
uptimeSeconds = getPrettyTime(uptimeSeconds)
uptimeSeconds2 = getPrettyTime(uptimeSeconds2)
# add uptime and battery info to the bot response
bot_response += "\nUptime:" + str(uptimeSeconds) + designator
bot_response += "\nUptime:" + str(uptimeSeconds)
if interface2_enabled:
bot_response += f" P2:" + {uptimeSeconds2} + {designator}
bot_response += f" P2:" + {uptimeSeconds2}
if not batteryLevel == 101:
bot_response += f" Bat: {batteryLevel}% Volt: {voltage}"
if interface2_enabled and not batteryLevel2 == 101:
bot_response += f" P2: Bat: {batteryLevel2}% Volt: {voltage2}"
# show last users of the bot with the cmdHistory list
history = handle_history(nodeid, deviceID, lheard=True)
history = handle_history(message, nodeid, deviceID, isDM, lheard=True)
if history:
bot_response += f'\n{history}'
return bot_response
def handle_history(nodeid, deviceID, lheard=False):
def handle_history(message, nodeid, deviceID, isDM, lheard=False):
global cmdHistory, lheardCmdIgnoreNode, bbs_admin_list
msg = ""
buffer = []
# show the last commands from the user to the bot
if not lheard:
if "?" in message and isDM:
return message.split("?")[0].title() + " command returns a list of commands received."
# show the last commands from the user to the bot
elif not lheard:
for i in range(len(cmdHistory)):
prettyTime = round((time.time() - cmdHistory[i]['time']) / 600) * 5
if prettyTime < 60:
prettyTime = str(prettyTime) + "m"
elif prettyTime < 1440:
prettyTime = str(round(prettyTime/60)) + "h"
else:
prettyTime = str(round(prettyTime/1440)) + "d"
cmdTime = round((time.time() - cmdHistory[i]['time']) / 600) * 5
prettyTime = getPrettyTime(cmdTime)
# history display output
if nodeid in bbs_admin_list and cmdHistory[i]['nodeID'] not in lheardCmdIgnoreNode:
@@ -570,13 +584,8 @@ def handle_history(nodeid, deviceID, lheard=False):
else:
# sort the cmdHistory list by time, return the username and time into a new list which used for display
for i in range(len(cmdHistory)):
prettyTime = round((time.time() - cmdHistory[i]['time']) / 600) * 5
if prettyTime < 60:
prettyTime = str(prettyTime) + "m"
elif prettyTime < 1440:
prettyTime = str(round(prettyTime/60)) + "h"
else:
prettyTime = str(round(prettyTime/1440)) + "d"
cmdTime = round((time.time() - cmdHistory[i]['time']) / 600) * 5
prettyTime = getPrettyTime(cmdTime)
if cmdHistory[i]['nodeID'] not in lheardCmdIgnoreNode:
# add line to a new list for display
@@ -608,28 +617,6 @@ def handle_moon(message_from_id, deviceID, channel_number):
location = get_node_location(message_from_id, deviceID, channel_number)
return get_moon(str(location[0]), str(location[1]))
def handle_ack(hop, snr, rssi):
if hop == "Direct":
return "✋ACK-ACK! " + f"SNR:{snr} RSSI:{rssi}"
else:
return "✋ACK-ACK! " + hop
def handle_testing(message, hop, snr, rssi):
if "@" in message:
if hop == "Direct":
return "🎙Testing, " + f"SNR:{snr} RSSI:{rssi}" + " at: " + message.split("@")[1]
else:
return "🎙Testing, " + hop + " at: " + message.split("@")[1]
elif "#" in message:
if hop == "Direct":
return "🎙Testing " + f"SNR:{snr} RSSI:{rssi}" + " #" + message.split("#")[1]
else:
return "🎙Testing " + hop + " #" + message.split("#")[1]
else:
if hop == "Direct":
return "🎙Testing 1,2,3 " + f"SNR:{snr} RSSI:{rssi}"
else:
return "🎙Testing 1,2,3 " + hop
def handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus):
loc = []
@@ -637,9 +624,9 @@ def handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus):
str(get_name_from_number(message_from_id, 'long', deviceID) + " AKA, " +\
str(get_name_from_number(message_from_id, 'short', deviceID)) + " AKA, " +\
str(decimal_to_hex(message_from_id)) + f"\n")
msg += f"I see the signal strength is {rssi} and the SNR is {snr} with hop count of {hop} \n"
if pkiStatus[0]:
msg += f"Your PKI bit is {pkiStatus[0]} pubKey: {pkiStatus[1]}"
msg += f"I see the signal strength is {rssi} and the SNR is {snr} with hop count of {hop}"
if pkiStatus[1] != 'ABC':
msg += f"\nYour PKI bit is {pkiStatus[0]} pubKey: {pkiStatus[1]}"
loc = get_node_location(message_from_id, deviceID)
if loc != [latitudeValue,longitudeValue]:
@@ -843,12 +830,9 @@ def onReceive(packet, interface):
# play the game
send_message(handleVideoPoker(message_from_id, message_string), channel_number, message_from_id, rxNode)
else:
# reset the player if the time exceeds 8 hours
vpTracker[i]['cmd'] = "gameOver"
vpTracker[i]['player'] = None
vpTracker[i]['deck'] = None
else:
# pop if the time exceeds 8 hours
vpTracker.pop(i)
for i in range(0, len(jackTracker)):
if jackTracker[i].get('nodeID') == message_from_id:
# check if the player has played in the last 8 hours
@@ -861,12 +845,8 @@ def onReceive(packet, interface):
# play the game
send_message(handleBlackJack(message_from_id, message_string), channel_number, message_from_id, rxNode)
else:
# reset the player if the time exceeds 8 hours
jackTracker[i]['cmd'] = "new"
jackTracker[i]['p_cards'] = []
jackTracker[i]['d_cards'] = []
jackTracker[i]['p_hand'] = []
jackTracker[i]['d_hand'] = []
# pop if the time exceeds 8 hours
jackTracker.pop(i)
else:
playingGame = False
@@ -885,23 +865,26 @@ def onReceive(packet, interface):
else:
# message is on a channel
if messageTrap(message_string):
# message is for bot to respond to
logger.info(f"Device:{rxNode} Channel:{channel_number} " + CustomFormatter.green + "Received: " + CustomFormatter.white + f"{message_string} " + CustomFormatter.purple +\
"From: " + CustomFormatter.white + f"{get_name_from_number(message_from_id, 'long', rxNode)}")
if useDMForResponse:
# respond to channel message via direct message
send_message(auto_response(message_string, snr, rssi, hop, pkiStatus, message_from_id, channel_number, rxNode, isDM), channel_number, message_from_id, rxNode)
if ignoreDefaultChannel and channel_number == publicChannel:
logger.debug(f"System: ignoreDefaultChannel CMD:{message_string} From: {get_name_from_number(message_from_id, 'short', rxNode)}")
else:
# or respond to channel message on the channel itself
if channel_number == publicChannel and antiSpam:
# warning user spamming default channel
logger.error(f"System: AntiSpam protection, sending DM to: {get_name_from_number(message_from_id, 'long', rxNode)}")
# message is for bot to respond to
logger.info(f"Device:{rxNode} Channel:{channel_number} " + CustomFormatter.green + "Received: " + CustomFormatter.white + f"{message_string} " + CustomFormatter.purple +\
"From: " + CustomFormatter.white + f"{get_name_from_number(message_from_id, 'long', rxNode)}")
if useDMForResponse:
# respond to channel message via direct message
send_message(auto_response(message_string, snr, rssi, hop, pkiStatus, message_from_id, channel_number, rxNode, isDM), channel_number, message_from_id, rxNode)
else:
# respond to channel message on the channel itself
send_message(auto_response(message_string, snr, rssi, hop, pkiStatus, message_from_id, channel_number, rxNode, isDM), channel_number, 0, rxNode)
# or respond to channel message on the channel itself
if channel_number == publicChannel and antiSpam:
# warning user spamming default channel
logger.error(f"System: AntiSpam protection, sending DM to: {get_name_from_number(message_from_id, 'long', rxNode)}")
# respond to channel message via direct message
send_message(auto_response(message_string, snr, rssi, hop, pkiStatus, message_from_id, channel_number, rxNode, isDM), channel_number, message_from_id, rxNode)
else:
# respond to channel message on the channel itself
send_message(auto_response(message_string, snr, rssi, hop, pkiStatus, message_from_id, channel_number, rxNode, isDM), channel_number, 0, rxNode)
else:
# message is not for bot to respond to
# ignore the message but add it to the message history list

View File

@@ -4,7 +4,7 @@
import pickle # pip install pickle
from modules.log import *
trap_list_bbs = ("bbslist", "bbspost", "bbsread", "bbsdelete", "bbshelp")
trap_list_bbs = ("bbslist", "bbspost", "bbsread", "bbsdelete", "bbshelp", "bbsinfo")
# global message list, later we will use a pickle on disk
bbs_messages = []
@@ -130,6 +130,11 @@ def bbs_post_dm(toNode, message, fromNode):
save_bbsdm()
return "BBS DM Posted for node " + str(toNode)
def get_bbs_stats():
global bbs_messages, bbs_dm
# Return some stats on the bbs pending messages and total posted messages
return f"📡BBSdb has {len(bbs_messages)} messages. Direct ✉️ Messages waiting: {(len(bbs_dm) - 1)}"
def bbs_check_dm(toNode):
global bbs_dm
# Check for any messages for toNode

View File

@@ -4,6 +4,7 @@
from random import choices, shuffle
from modules.log import *
import time
import pickle
jack_starting_cash = 100 # Replace 100 with your desired starting cash value
jackTracker= [{'nodeID': 0, 'cmd': 'new', 'time': time.time(), 'cash': jack_starting_cash,\
@@ -113,15 +114,6 @@ class jackChips:
self.total -= self.bet
self.winnings -= 1
def take_bet(bet_amount, player_money):
try:
if bet_amount >= player_money or bet_amount <= 0:
return f"Enter a bet amount between 1 and {player_money}"
return bet_amount
except TypeError:
return "Invalid bet amount"
def success_rate(card, obj_h):
""" Calculate Success rate of 'HIT' new cards """
msg = ""
@@ -132,13 +124,11 @@ def success_rate(card, obj_h):
if rate < 100:
msg += f"If Hit, chance {int(rate)}% failure, {100-int(rate)}% success."
elif rate > 100:
else:
l_rate = int(rate - (rate - 99)) # Round to 99
if card[0][1] == "A":
l_rate -= 99
msg += f"If Hit, chance {100-l_rate}% failure, and {l_rate}% success"
else:
msg += "If Hit, a low chance of success."
return msg
def hits(obj_de):
@@ -216,9 +206,33 @@ def setLastCmdJack(nodeID, cmd):
return True
return False
def saveHSJack(nodeID, highScore):
# Save the game state to pickle
highScore = {'nodeID': nodeID, 'highScore': highScore}
try:
with open('blackjack_hs.pkl', 'wb') as file:
pickle.dump(highScore, file)
except FileNotFoundError:
logger.debug("System: BlackJack: Creating new blackjack_hs.pkl file")
with open('blackjack_hs.pkl', 'wb') as file:
pickle.dump(highScore, file)
def loadHSJack():
try:
with open('blackjack_hs.pkl', 'rb') as file:
highScore = pickle.load(file)
return highScore
except FileNotFoundError:
logger.debug("System: BlackJack: Creating new blackjack_hs.pkl file")
highScore = {'nodeID': 0, 'highScore': 0}
with open('blackjack_hs.pkl', 'wb') as file:
pickle.dump(highScore, file)
return 0
def playBlackJack(nodeID, message):
# Initalize the Game
msg, last_cmd = '', None
blackJack = False
p_win, d_win, draw = 0, 0, 0
p_chips = jackChips()
p_hand = jackHand()
@@ -243,8 +257,8 @@ def playBlackJack(nodeID, message):
d_win = jackTracker[i]['gameStats']['d_win']
draw = jackTracker[i]['gameStats']['draw']
bet_money = jackTracker[i]['bet']
p_chips.bet = bet_money
if last_cmd == "playing":
p_chips.bet = bet_money
p_cards = jackTracker[i]['p_cards']
d_cards = jackTracker[i]['d_cards']
p_hand = jackTracker[i]['p_hand']
@@ -256,39 +270,44 @@ def playBlackJack(nodeID, message):
logger.debug(f"System: BlackJack: New Player {nodeID}")
jackTracker.append({'nodeID': nodeID, 'cmd': 'new', 'time': time.time(), 'cash': jack_starting_cash,\
'bet': 0, 'gameStats': {'p_win': p_win, 'd_win': d_win, 'draw': draw}, 'p_cards':p_cards, 'd_cards':d_cards, 'p_hand':p_hand.cards, 'd_hand':d_hand.cards, 'next_card':next_card})
return f"Welcome to BlackJack!♠️♥️♣️♦️ you have {p_chips.total} chips. Game Played via Direct Message. Whats your bet?"
return f"Welcome to ♠️♥️BlackJack♣ you have {p_chips.total} chips. Whats your bet?"
if getLastCmdJack(nodeID) == "new":
# Place Bet
try:
# handle B letter
if message == "b":
if message.lower() == "b":
if bet_money == 0:
bet_money = 5
else:
bet_money = bet_money
elif message.lower() == "r":
#resend the hand
msg += show_some(p_cards, d_cards, p_hand)
return msg
else:
bet_money = int(message)
try:
bet_money = int(message)
except ValueError:
return "Invalid Bet, please enter a valid number."
if bet_money <= p_chips.total or bet_money <= 1:
p_chips.bet = take_bet(bet_money, p_chips.total)
if bet_money <= p_chips.total and bet_money >= 1:
p_chips.bet = bet_money
else:
return f"Invalid Bet, the maximum bet you can place is {p_chips.total}"
return f"Invalid Bet, the maximum bet you can place is {p_chips.total} and the minimum bet is 1."
except ValueError:
return f"Invalid Bet, the maximum bet, {p_chips.total}"
# Show the cards
msg += show_some(p_cards, d_cards, p_hand)
# check for blackjack 21 and only two cards
if p_hand.value == 21 and len(p_hand.cards) == 2:
msg += "Player 🎰 BLAAAACKJACKKKK 💰"
p_chips.total += round(p_chips.bet * 1.5)
setLastCmdJack(nodeID, "dealerTurn")
blackJack = True
# Save the game state
for i in range(len(jackTracker)):
if jackTracker[i]['nodeID'] == nodeID:
jackTracker[i]['cash'] = p_chips.total
jackTracker[i]['cash'] = int(p_chips.total)
break
else:
# Display the statistics
@@ -296,10 +315,9 @@ def playBlackJack(nodeID, message):
msg += stats
setLastCmdJack(nodeID, "betPlaced")
if getLastCmdJack(nodeID) == "betPlaced":
setLastCmdJack(nodeID, "playing")
msg += "(H)it,(S)tand,(F)orfit,(D)ouble"
msg += "(H)it,(S)tand,(F)orfit,(D)ouble,(R)esend,(L)eave table"
# save the game state
for i in range(len(jackTracker)):
@@ -341,27 +359,29 @@ def playBlackJack(nodeID, message):
setLastCmdJack(nodeID, "dealerTurn")
else:
return "You can't Double Down, dont have enough chips"
elif choice == "resend" or choice == "r":
msg += show_some(p_hand.cards, d_cards, p_hand)
else:
return "Invalid Choice"
return "(H)it,(S)tand,(F)orfit,(D)ouble,(R)esend,(L)eave table"
# Check if player bust
if player_bust(p_hand, p_chips):
d_win += 1
msg += "Player:BUST💥"
msg += "💥PlayerBUST💥"
setLastCmdJack(nodeID, "dealerTurn")
if getLastCmdJack(nodeID) == "playing":
msg += stats
msg += "[H,S,F,D,L]"
msg += "[H,S,F,D]"
# Save the game state
for i in range(len(jackTracker)):
if jackTracker[i]['nodeID'] == nodeID:
jackTracker[i]['cash'] = p_chips.total
jackTracker[i]['bet'] = p_chips.bet
jackTracker[i]['gameStats']['p_win'] = p_win
jackTracker[i]['gameStats']['d_win'] = d_win
jackTracker[i]['gameStats']['draw'] = draw
jackTracker[i]['cash'] = int(p_chips.total)
jackTracker[i]['bet'] = int(p_chips.bet)
jackTracker[i]['gameStats']['p_win'] = int(p_win)
jackTracker[i]['gameStats']['d_win'] = int(d_win)
jackTracker[i]['gameStats']['draw'] = int(draw)
jackTracker[i]['p_cards'] = p_cards
jackTracker[i]['d_cards'] = d_cards
jackTracker[i]['p_hand'] = p_hand
@@ -375,20 +395,22 @@ def playBlackJack(nodeID, message):
return msg
if getLastCmdJack(nodeID) == "dealerTurn":
# Dealers Turn
if not blackJack:
# recall the game state
for i in range(len(jackTracker)):
if jackTracker[i]['nodeID'] == nodeID:
p_chips.total = int(jackTracker[i]['cash'])
p_chips.bet = int(jackTracker[i]['bet'])
p_win = int(jackTracker[i]['gameStats']['p_win'])
d_win = int(jackTracker[i]['gameStats']['d_win'])
draw = jackTracker[i]['gameStats']['draw']
p_cards = jackTracker[i]['p_cards']
d_cards = jackTracker[i]['d_cards']
p_hand = jackTracker[i]['p_hand']
d_hand = jackTracker[i]['d_hand']
next_card = jackTracker[i]['next_card']
break
for i in range(len(jackTracker)):
if jackTracker[i]['nodeID'] == nodeID:
p_chips.total = jackTracker[i]['cash']
p_chips.bet = jackTracker[i]['bet']
p_win = jackTracker[i]['gameStats']['p_win']
d_win = jackTracker[i]['gameStats']['d_win']
draw = jackTracker[i]['gameStats']['draw']
p_cards = jackTracker[i]['p_cards']
d_cards = jackTracker[i]['d_cards']
p_hand = jackTracker[i]['p_hand']
d_hand = jackTracker[i]['d_hand']
next_card = jackTracker[i]['next_card']
break
if p_hand.value <= 21:
# Dealer's Turn
@@ -397,7 +419,7 @@ def playBlackJack(nodeID, message):
d_hand.add_cards(d_card)
if dealer_bust(d_hand, p_hand, p_chips):
p_win += 1
msg += "Dealer:BUST💥"
msg += "💰DealerBUST💥"
break
# Show all cards
msg += show_all(p_hand.cards, d_hand.cards, p_hand, d_hand)
@@ -423,12 +445,18 @@ def playBlackJack(nodeID, message):
if p_chips.total > 0:
msg += "🪙Keep the change you filthy animal!"
else:
msg += "💸NO MORE MONEY! Game Over!"
msg += "💸NO MORE CHIPS!🏧💳"
p_chips.total = jack_starting_cash
else:
msg += f"💰You have {p_chips.total} chips left"
# check high score
highScore = loadHSJack()
if highScore != 0 and p_chips.total > highScore['highScore']:
msg += f"💰HighScore💰{p_chips.total} "
saveHSJack(nodeID, p_chips.total)
else:
msg += f"💰You have {p_chips.total} chips "
msg += "(B)et or (L)eave table."
msg += " Bet or Leave?"
# Reset the game
setLastCmdJack(nodeID, "new")

View File

@@ -204,7 +204,7 @@ def buy_func(nodeID, price_list, choice=0, value='0'):
if drug_choice in range(1, len(my_drugs) + 1):
drug_choice = drug_choice - 1
msg = my_drugs[drug_choice].name + ": you have🎒 " + str(amount[drug_choice]) + " "
msg += " The going price is: $" + str(price_list[drug_choice]) + " "
msg += " The going price is: $" + "{:,}".format(price_list[drug_choice]) + " "
buy_amount = value
if buy_amount == 'm':
@@ -228,7 +228,7 @@ def buy_func(nodeID, price_list, choice=0, value='0'):
cash -= buy_amount * price_list[drug_choice]
inventory += buy_amount
msg += "You bought " + str(buy_amount) + " " + my_drugs[drug_choice].name + '. Remaining cash: $' + str(cash)
msg += f"\nBuy Sell Fly?"
msg += f"\nBuy💸, Sell💰, Fly🛫?"
else:
msg = "You don't have enough cash!😭"
return msg
@@ -294,7 +294,7 @@ def sell_func(nodeID, price_list, choice=0, value='0'):
cash += sell_amount * price_list[drug_choice]
inventory -= sell_amount
msg += " You sold " + str(sell_amount) + " " + my_drugs[drug_choice].name + ' for $' +\
str(sell_amount * price_list[drug_choice]) + '. Total cash: $' + str(cash)
str(sell_amount * price_list[drug_choice]) + '. Total cash: $' + "{:,}".format(cash)
else:
msg = "You don't have that much"
return msg
@@ -421,11 +421,11 @@ def render_game_screen(userID, day_play, total_day, loc_choice, event_number, pr
if dwCashDb[i].get('userID') == userID:
cash = dwCashDb[i].get('cash')
msg += "Location: " + loc[int(loc_choice) - 1] + ", Day:" + str(day_play) + '/' + str(total_day) + " 🎒: " + str(inventory) + "/100" + ", $" + str(cash) + f"\n"
msg += "🗺️" + loc[int(loc_choice) - 1] + " 📆" + str(day_play) + '/' + str(total_day) + " 🎒" + str(inventory) + "/100" + " 💵" + "{:,}".format(cash) + f"\n"
for i, drug in enumerate(my_drugs, 1):
qty = amount[i-1]
msg += f'#{str(i)}.{drug.name}/${price_list[i-1]}({qty}) '
msg += f'#{str(i)}.{drug.name}${"{:,}".format(price_list[i-1])}({qty}) '
return msg
@@ -516,7 +516,7 @@ def playDopeWars(nodeID, cmd):
dwPlayerTracker[i]['cmd'] = 'location'
if last_cmd == 'ask_bsf':
msg = 'example Buy: b,Drug,Qty or Sell s,1,10. Fly: f. Price list: p or end'
msg = f'example buy:\nb,drug#,qty# or Sell: s,1,10 qty can be (m)ax\n f,p or end'
menu_choice = cmd.lower()
if ',' in menu_choice or '.' in menu_choice:
#split the choice into a letter and a number for the buy/sell functions
@@ -539,7 +539,7 @@ def playDopeWars(nodeID, cmd):
menu_choice[2] = int(menu_choice[2])
except ValueError:
msg = 'a value was bad, example dopeware Buy or Sell b,1,10 or s,1,m'
msg = f'a value was bad, example dopeware Buy or Sell\n b,1,10 or s,1,m'
return msg
if menu_choice[0] == 'b':
@@ -589,7 +589,7 @@ def playDopeWars(nodeID, cmd):
msg = endGameDw(nodeID)
return msg
else:
msg = 'example Buy: b,Drug,Qty or Sell s,1,10. Fly: f. Price list: p or end'
msg = f'example buy:\nb,drug#,qty# or Sell: s,1,10 qty can be (m)ax\n f,p or end'
return msg
# Buy
@@ -639,7 +639,7 @@ def playDopeWars(nodeID, cmd):
# Display Main Game Screen and ask for buy, sell, or fly
if last_cmd == 'display_main':
msg = dopeWarGameDay(nodeID, game_day, total_days)
msg += f"\nBuy, Sell, Fly? Price list?"
msg += f"\nBuy💸, Sell💰, (F)ly🛫? (P)riceList?"
# set the player's last command
for i in range(0, len(dwPlayerTracker)):
if dwPlayerTracker[i].get('userID') == nodeID:

View File

@@ -38,15 +38,13 @@ def get_sales_amount(potential, unit, price):
return math.floor(potential * (unit / (price ** 1.5)))
def getHighScoreLemon():
global high_score
high_score = {"userID": 0, "cash": 0, "success": 0}
# Load high score table
try:
with open('lemonade_hs.pkl', 'rb') as file:
high_score = pickle.load(file)
except FileNotFoundError:
logger.debug("System: Lemonade: No high score table found")
# high score pickle file is a touple of the nodeID and the high score
high_score = ({"userID": 4258675309, "cash": 2, "success": 0})
# write a new high score file if one is not found
with open('lemonade_hs.pkl', 'wb') as file:
pickle.dump(high_score, file)

View File

@@ -59,14 +59,14 @@ stdout_handler.setFormatter(CustomFormatter(logFormat))
logger.addHandler(stdout_handler)
if syslog_to_file:
# Create file handler for logging to a file
file_handler = logging.FileHandler('system{}.log'.format(today.strftime('%Y_%m_%d')))
file_handler = logging.FileHandler('logs/system{}.log'.format(today.strftime('%Y_%m_%d')))
file_handler.setLevel(logging.DEBUG) # DEBUG used by default for system logs to disk
file_handler.setFormatter(logging.Formatter(logFormat))
logger.addHandler(file_handler)
if log_messages_to_file:
# Create file handler for logging to a file
file_handler = logging.FileHandler('messages{}.log'.format(today.strftime('%Y_%m_%d')))
file_handler = logging.FileHandler('logs/messages{}.log'.format(today.strftime('%Y_%m_%d')))
file_handler.setLevel(logging.INFO) # INFO used for messages to disk
file_handler.setFormatter(logging.Formatter(msgLogFormat))
msgLogger.addHandler(file_handler)

View File

@@ -94,6 +94,7 @@ try:
# general
useDMForResponse = config['general'].getboolean('respond_by_dm_only', True)
publicChannel = config['general'].getint('defaultChannel', 0) # the meshtastic public channel
ignoreDefaultChannel = config['general'].getboolean('ignoreDefaultChannel', False)
zuluTime = config['general'].getboolean('zuluTime', False) # aka 24 hour time
log_messages_to_file = config['general'].getboolean('LogMessagesToFile', True) # default True
syslog_to_file = config['general'].getboolean('SyslogToFile', False)

View File

@@ -85,7 +85,7 @@ if dad_jokes_enabled:
# Wikipedia Search Configuration
if wikipedia_enabled:
import wikipedia # pip install wikipedia
trap_list = trap_list + ("wiki:",)
trap_list = trap_list + ("wiki:", "wiki?",)
help_message = help_message + ", wiki:"
# LLM Configuration
@@ -129,7 +129,6 @@ if games_enabled is True:
if lemonade_enabled:
gamesCmdList += "LemonStand, "
if gTnW_enabled:
import random
trap_list = trap_list + ("globalthermonuclearwar",)
if blackjack_enabled:
gamesCmdList += "BlackJack, "
@@ -586,6 +585,23 @@ def get_wikipedia_summary(search_term):
return summary
def getPrettyTime(seconds):
# convert unix time to minutes, hours, or days, or years for simple display
designator = "s"
if seconds > 0:
seconds = round(seconds / 60)
designator = "m"
if seconds > 60:
seconds = round(seconds / 60)
designator = "h"
if seconds > 24:
seconds = round(seconds / 24)
designator = "d"
if seconds > 365:
seconds = round(seconds / 365)
designator = "y"
return str(seconds) + designator
def messageTrap(msg):
# Check if the message contains a trap word, this is the first filter for listning to messages
# after this the message is passed to the command_handler in the bot.py which is switch case filter for applying word to function

View File

@@ -2,6 +2,7 @@
# Adapted for Meshtastic mesh-bot by K7MHI Kelly Keeton 2024
import random
import time
import pickle
from modules.log import *
vpStartingCash = 20
@@ -272,6 +273,30 @@ def setLastCmdVp(nodeID, cmd):
if vpTracker[i]['nodeID'] == nodeID:
vpTracker[i]['cmd'] = cmd
def saveHSVp(nodeID, highScore):
# Save the game high_score to pickle
highScore = {'nodeID': nodeID, 'highScore': highScore}
try:
with open('videopoker_hs.pkl', 'wb') as file:
pickle.dump(highScore, file)
except FileNotFoundError:
logger.debug("System: BlackJack: Creating new videopoker_hs.pkl file")
with open('videopoker_hs.pkl', 'wb') as file:
pickle.dump(highScore, file)
def loadHSVp():
# Load the game high_score from pickle
try:
with open('videopoker_hs.pkl', 'rb') as file:
highScore = pickle.load(file)
return highScore
except FileNotFoundError:
logger.debug("System: VideoPoker: Creating new videopoker_hs.pkl file")
highScore = {'nodeID': 0, 'highScore': 0}
with open('videopoker_hs.pkl', 'wb') as file:
pickle.dump(highScore, file)
return 0
def playVideoPoker(nodeID, message):
msg = ""
@@ -280,7 +305,7 @@ def playVideoPoker(nodeID, message):
# create new player if not in tracker
logger.debug(f"System: VideoPoker: New Player {nodeID}")
vpTracker.append({'nodeID': nodeID, 'cmd': 'new', 'time': time.time(), 'cash': vpStartingCash, 'player': None, 'deck': None, 'highScore': 0, 'drawCount': 0})
return f"Welcome to 🎰 VideoPoker! you have {vpStartingCash} coins, Game Played via Direct Message. Whats your bet?"
return f"Welcome to 🎰VideoPoker♥️ you have {vpStartingCash} coins, Whats your bet?"
# Gather the player's bet
if getLastCmdVp(nodeID) == "new" or getLastCmdVp(nodeID) == "gameOver":
@@ -344,7 +369,7 @@ def playVideoPoker(nodeID, message):
vpTracker[i]['deck'] = deck
vpTracker[i]['drawCount'] = drawCount
msg += f"\nDeal new card? \nex: 1,3,4 or (N)o,(A)ll"
msg += f"\nDeal new card? \nex: 1,3,4 or (N)o,(A)ll (H)and"
setLastCmdVp(nodeID, "redraw")
return msg
@@ -406,6 +431,8 @@ def playVideoPoker(nodeID, message):
elif player.bankroll > vpTracker[i]['highScore']:
vpTracker[i]['highScore'] = player.bankroll
msg += " 🎉HighScore!"
# save high score
saveHSVp(nodeID, vpTracker[i]['highScore'])
msg += f"\nPlace your Bet, 'L' to leave the game."