Skip to content
This repository has been archived by the owner on Jan 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2 from ilyash0/dev
Browse files Browse the repository at this point in the history
v0.3.0
  • Loading branch information
ilyash0 authored Aug 12, 2023
2 parents a0367ce + e341325 commit 4ee8fbf
Show file tree
Hide file tree
Showing 65 changed files with 3,753 additions and 1,865 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ pip-delete-this-directory.txt
.idea/

logs/
/reboot.sh
31 changes: 11 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,29 @@
<h1 align="center">
Puffle Bot for Discord
Puffle Bot
</h1>

#

<div align="center">

[![Github All Releases](https://img.shields.io/github/v/release/ilyash0/discord-bot)](https://github.com/ilyash0/discord-bot/releases)
[![Github All Releases](https://img.shields.io/github/v/release/ilyash0/puffle-bot)](https://github.com/ilyash0/puffle-bot/releases)
[![Custom badge](https://img.shields.io/badge/-add%20bot%20to%20server-5865F2)](https://discord.com/api/oauth2/authorize?client_id=875078308688179200&permissions=412317240384&scope=applications.commands%20bot)
[![Discord](https://img.shields.io/discord/755445822920982548?logo=discord&logoColor=white)](https://discord.gg/ntZUXsWZaM)
[![Discord](https://img.shields.io/discord/755445822920982548?logo=discord&logoColor=white&label=discord)](https://discord.gg/ntZUXsWZaM)
</div>

<p align="center">A Discord bot with Club Penguin Private Server (specifically CPPS.app) written in Python 3.</p>
<p align="center">A public Discord bot for interaction with online game "CPPS.APP".</p>

- [Place for Terms of Service]()
- [Place for Documentation]()

## Features

- **Commands**: Use a slash-commands.
- **Database**: Combines with a database from CPPS.
- **Integration**: link CP and Discord accounts.
- **Pay**: Transfer coins from one penguin to another

## Installation

Puffle bot can be run as a normal Python program under any operating system. Do not forget to substitute your data, such as a `<bot_token>`(without <>)

```shell
$ git clone https://github.com/ilyash0/Puffle-bot
$ cd Puffle-bot
$ pip install -r requirements.txt
$ python /Puffle-bot/bootstrap.py -du <db_username> -dp <db_password> -dn <db_name> -p <port> -t <bot_token> &
```
- **Integration**: link CP and Discord accounts;
- **Commands**: Use a slash-commands for:
- Transfer coins;
- View penguin profile;
- View players online;
- And more.
- **Liked roles**: Create you own linked roles with Puffle Bot.

## Screenshots

Expand Down
8 changes: 6 additions & 2 deletions bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
default='password',
help='Postgresql database password')
database_group.add_argument('-dn', '--database-name', action='store',
dest='database_name',
dest='database_name_cp',
default='postgres',
help='Postgresql database name')
help='Postgresql database name for club penguin')
database_group.add_argument('-dn2', '--database-name2', action='store',
dest='database_name_pb',
default='pufflebot',
help='Postgresql database name for puffle bot')

args = parser.parse_args()

Expand Down
165 changes: 165 additions & 0 deletions bot/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import asyncio
import importlib
import logging
import pkgutil
from abc import ABC, abstractmethod
from collections import OrderedDict
from types import FunctionType


def get_package_modules(package):
package_modules = []
for importer, module_name, is_package in pkgutil.iter_modules(package.__path__):
full_module_name = f'{package.__name__}.{module_name}'
subpackage_object = importlib.import_module(full_module_name, package=package.__path__)
if is_package:
sub_package_modules = get_package_modules(subpackage_object)

package_modules = package_modules + sub_package_modules
package_modules.append(subpackage_object)
return package_modules


class _AbstractManager(dict):
def __init__(self, server):
self.server = server
self.logger = logging.getLogger('houdini')

super().__init__()

@abstractmethod
async def setup(self, module):
"""Setup manager class"""

@abstractmethod
async def load(self, module):
"""Loads entries from module"""


class ITable(ABC):
"""
All table game logic classes must implement this interface.
"""

@abstractmethod
def make_move(self, *args):
"""Tells logic a move has been made."""

@abstractmethod
def is_valid_move(self, *args):
"""Returns true if the move is valid."""

@abstractmethod
def get_string(self):
"""Returns string representation of the game."""


class IWaddle(ABC):
"""
All waddle game logic classes must implement this interface.
"""

@property
@abstractmethod
def room_id(self):
"""External ID of waddle game room."""

def __init__(self, waddle):
self.penguins = list(waddle.penguins)
self.seats = waddle.seats

async def start(self):
room_id = type(self).room_id
for penguin in self.penguins:
penguin.waddle = self
await penguin.join_room(penguin.server.rooms[room_id])

async def remove_penguin(self, p):
self.penguins[self.penguins.index(p)] = None
p.waddle = None

async def send_xt(self, *data, f=None):
for penguin in filter(f, self.penguins):
if penguin is not None:
await penguin.send_xt(*data)

def get_seat_id(self, p):
return self.penguins.index(p)


class PenguinStringCompiler(OrderedDict):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def __setitem__(self, key, compiler_method):
assert type(compiler_method) == FunctionType
super().__setitem__(key, compiler_method)

async def compile(self, p):
compiler_method_results = []

for compiler_method in self.values():
if asyncio.iscoroutinefunction(compiler_method):
compiler_method_result = await compiler_method(p)
else:
compiler_method_result = compiler_method(p)
compiler_method_results.append(str(compiler_method_result))

compiler_result = '|'.join(compiler_method_results)
return compiler_result

@classmethod
def attribute_by_name(cls, attribute_name):
async def attribute_method(p):
return getattr(p, attribute_name) or 0
return attribute_method

@classmethod
def custom_attribute_by_name(cls, attribute_name):
async def attribute_method(p):
return p.get_custom_attribute(attribute_name, '')
return attribute_method

@classmethod
def setup_default_builder(cls, string_builder):
string_builder.update({
'ID': PenguinStringCompiler.attribute_by_name('id'),
'Nickname': PenguinStringCompiler.attribute_by_name('nickname'),
'Approval': PenguinStringCompiler.attribute_by_name('approval'),
'Color': PenguinStringCompiler.attribute_by_name('color'),
'Head': PenguinStringCompiler.attribute_by_name('head'),
'Face': PenguinStringCompiler.attribute_by_name('face'),
'Neck': PenguinStringCompiler.attribute_by_name('neck'),
'Body': PenguinStringCompiler.attribute_by_name('body'),
'Hand': PenguinStringCompiler.attribute_by_name('hand'),
'Feet': PenguinStringCompiler.attribute_by_name('feet'),
'Flag': PenguinStringCompiler.attribute_by_name('flag'),
'Photo': PenguinStringCompiler.attribute_by_name('photo'),
'X': PenguinStringCompiler.attribute_by_name('x'),
'Y': PenguinStringCompiler.attribute_by_name('y'),
'Frame': PenguinStringCompiler.attribute_by_name('frame'),
'Member': PenguinStringCompiler.attribute_by_name('member'),
'MemberDays': PenguinStringCompiler.attribute_by_name('membership_days_total'),
'Avatar': PenguinStringCompiler.attribute_by_name('avatar'),
'PenguinState': PenguinStringCompiler.attribute_by_name('penguin_state'),
'PartyState': PenguinStringCompiler.attribute_by_name('party_state'),
'PuffleState': PenguinStringCompiler.attribute_by_name('puffle_state')
})

@classmethod
def setup_anonymous_default_builder(cls, string_builder):
string_builder.update({
'ID': PenguinStringCompiler.attribute_by_name('id'),
'Nickname': PenguinStringCompiler.attribute_by_name('nickname'),
'Approval': PenguinStringCompiler.attribute_by_name('approval'),
'Color': PenguinStringCompiler.attribute_by_name('color'),
'Head': PenguinStringCompiler.attribute_by_name('head'),
'Face': PenguinStringCompiler.attribute_by_name('face'),
'Neck': PenguinStringCompiler.attribute_by_name('neck'),
'Body': PenguinStringCompiler.attribute_by_name('body'),
'Hand': PenguinStringCompiler.attribute_by_name('hand'),
'Feet': PenguinStringCompiler.attribute_by_name('feet'),
'Flag': PenguinStringCompiler.attribute_by_name('flag'),
'Photo': PenguinStringCompiler.attribute_by_name('photo')
})
Loading

0 comments on commit 4ee8fbf

Please sign in to comment.