from os import write
from time import time

from esp_hadouken.GameChild import *

class HighScores(GameChild, list):

    def __init__(self, parent):
        GameChild.__init__(self, parent)
        list.__init__(self, [])
        self.read()

    def read(self):
        for line in open(self.get_path()):
            line = line.strip()
            if line:
                self.append(Score(*line.split(" ")))

    def get_path(self):
        return self.get_resource("scoreboard-scores-path")

    def add(self, player):
        timer = self.get_timer()
        values = (timer["octo"], timer["horse"], timer["diortem"],
                  timer["circulor"], timer["tooth"])
        score = Score(time(), player, timer.total(), *values)
        self.append(score)
        self.write(score)

    def write(self, score):
        scores = open(self.get_path(), "a")
        scores.write(str(score) + "\n")

    def get_most_recent_player(self):
        return self[-1].player


class Score:

    def __init__(self, *args):
        self.date = int(args[0])
        self.player = args[1]
        self.total, self.octo, self.horse, self.diortem, self.circulor, \
                    self.tooth = map(float, args[2:])

    def __str__(self):
        return "%i %s %.3f %.3f %.3f %.3f %.3f %.3f" % \
               (self.date, self.player, self.total, self.octo, self.horse,
                self.diortem, self.circulor, self.tooth)

    def __lt__(self, other):
        return self.total < other.total

    def __repr__(self):
        return self.__str__()
from pygame import Surface

from esp_hadouken.GameChild import *
from esp_hadouken.Input import *
from Row import *
from Heading import *

class Scoreboard(GameChild, Surface):

    active_interval = 0

    def __init__(self, parent):
        GameChild.__init__(self, parent)
        self.init_surface()
        self.set_rect()
        self.heading = Heading(self)
        self.add_rows()
        self.subscribe_to(Input.command_event, self.respond_to_command)
        self.deactivate()

    def init_surface(self):
        config = self.get_configuration()
        step = self.get_step()
        padding = self.get_padding()
        row_height = self.get_row_height()
        height = step * row_height + padding + self.get_heading_height()
        Surface.__init__(self, (config["scoreboard-width"], height))
        self.set_alpha(config["scoreboard-alpha"])

    def get_step(self):
        return self.get_configuration()["scoreboard-interval-length"]

    def get_row_height(self):
        return self.get_configuration()["scoreboard-row-height"]

    def get_padding(self):
        return self.get_configuration()["scoreboard-padding"]

    def get_heading_height(self):
        return self.get_configuration()["scoreboard-heading-height"]
    
    def get_column_widths(self):
        return self.get_configuration()["scoreboard-column-widths"]

    def set_rect(self):
        rect = self.get_rect()
        rect.center = self.get_screen().get_rect().center
        self.rect = rect

    def add_rows(self):
        rows = []
        for ii in range(self.get_step()):
            rows.append(Row(self, ii))
        self.rows = rows

    def respond_to_command(self, event):
        if self.active:
            command = event.command
            if command == "next":
                self.set_active_interval(1)
                self.populate()
            elif command == "previous":
                self.set_active_interval(-1)
                self.populate()

    def set_active_interval(self, increment=0, interval=None):
        if interval is None:
            interval = self.active_interval + increment
        max_interval = self.get_max_interval()
        if interval < 0:
            interval = 0
        elif interval > max_interval:
            interval = max_interval
        self.active_interval = interval

    def get_max_interval(self):
        return len(self.get_high_scores()) / self.get_step()

    def populate(self):
        self.disable_highlights()
        step = self.get_step()
        low = step * self.active_interval
        high = low + step
        interval = self.get_ordered_scores()[low:high]
        interval += [None] * (step - len(interval))
        rows = self.rows
        for ii, score in enumerate(interval):
            score_index = low + ii
            row = rows[ii]
            if score_index == self.get_highlit_score_index():
               row.enable_highlight() 
            row.set_score(score, score_index)
        self.parent.update()

    def disable_highlights(self):
        for row in self.rows:
            row.disable_highlight()

    def get_ordered_scores(self):
        return sorted(self.get_high_scores())

    def activate(self, highlight=True):
        self.active = True
        if highlight:
            self.show_recent_score_interval()
        self.populate()

    def show_recent_score_interval(self):
        ordered = self.get_ordered_scores()
        interval = self.get_highlit_score_index() / self.get_step()
        self.set_active_interval(interval=interval)

    def get_highlit_score_index(self):
        return self.get_ordered_scores().index(self.get_high_scores()[-1])

    def deactivate(self):
        self.active = False

    def update(self):
        if self.active:
            self.clear()
            self.heading.update()
            for row in self.rows:
                row.update()
            self.draw()

    def clear(self):
        self.fill(Color(self.get_configuration()["scoreboard-bg"]))

    def draw(self):
        self.parent.blit(self, self.rect)
from pygame import Surface, Color
from pygame.locals import *

from esp_hadouken.GameChild import *
from esp_hadouken.Font import *

class Row(GameChild, Surface):

    def __init__(self, parent, index):
        GameChild.__init__(self, parent)
        self.index = index
        self.disable_highlight()
        self.init_surface()
        self.set_rect()
        self.set_column_surfaces()

    def enable_highlight(self):
        self.highlit = True

    def disable_highlight(self):
        self.highlit = False

    def init_surface(self):
        parent = self.parent
        width = parent.get_width() - parent.get_padding()
        Surface.__init__(self, (width, parent.get_row_height()))
        self.fill(self.get_color())

    def get_color(self):
        config = self.get_configuration()
        if self.highlit:
            color = config["scoreboard-highlight-color"]
        elif not self.index % 2:
            color = config["scoreboard-row-color-1"]
        else:
            color = config["scoreboard-row-color-2"]
        return Color(color)

    def set_rect(self):
        rect = self.get_rect()
        parent = self.parent
        index = self.index
        padding = parent.get_padding()
        heading = parent.get_heading_height()
        rect.top = padding / 2 + index * parent.get_row_height() + heading
        rect.centerx = parent.get_rect().centerx
        self.rect = rect

    def set_column_surfaces(self):
        self.rank_surf, self.rank_surf_r = self.set_column_surface(0)
        self.initials_surf, self.initials_surf_r = self.set_column_surface(1)
        self.total_surf, self.total_surf_r = self.set_column_surface(2)
        self.split_surfs, self.split_surfs_rs = [], []
        for ii in range(3, 8):
            surf, rect = self.set_column_surface(ii)
            self.split_surfs.append(surf)
            self.split_surfs_rs.append(rect)

    def set_column_surface(self, index):
        ratios = self.parent.get_column_widths()
        relative = self.get_size()
        surf = Surface((relative[0] * ratios[index], relative[1]))
        surf.fill(self.get_color())
        indent = 0
        for ratio in ratios[:index]:
            indent += ratio * relative[0]
        rect = surf.get_rect()
        rect.left = indent
        return surf, rect

    def set_score(self, score, rank):
        self.render_rank(rank)
        self.render_initials(score)
        self.render_total(score)
        if score is None:
            splits = [None] * 5
        else:
            splits = [score.octo, score.horse, score.diortem, score.circulor,
                      score.tooth]
        for ii, split in enumerate(splits):
            self.render_split(ii, split)

    def render_rank(self, rank):
        size = self.get_configuration()["scoreboard-rank-size"]
        rend = Font(self, size).render(str(rank + 1), True, self.get_text_color(),
                                       self.get_color())
        rect = rend.get_rect()
        dest = self.rank_surf
        dest.fill(self.get_color())
        rect.center = dest.get_rect().center
        dest.blit(rend, rect)

    def get_text_color(self):
        return Color(self.get_configuration()["scoreboard-text-color"])

    def render_initials(self, score):
        self.initials_surf.fill(self.get_color())
        if score is None:
            return
        x = 0
        margin = self.get_configuration()["scoreboard-initials-margin"]
        size = self.get_height() - margin * 2
        for letter in score.player:
            self.render_initial(letter, x, size)
            x += size + margin

    def get_blank_char(self):
        return self.get_configuration()["scoreboard-blank-char"]

    def render_initial(self, letter, x, size):
        square = Surface((size, size))
        if letter == self.get_blank_char():
            color = self.get_configuration()["scoreboard-initials-blank-color"]
            color = Color(color)
        else:
            color = self.get_glyph_palette()[ord(letter.lower()) - K_a]
        square.fill(color)
        font_size = self.get_configuration()["scoreboard-initials-size"]
        rend = Font(self, font_size).render(letter, True, self.get_text_color(),
                                            color)
        square_rect = square.get_rect()
        rend_rect = rend.get_rect()
        rend_rect.center = square_rect.center
        square.blit(rend, rend_rect)
        square_rect.centery = self.get_rect().centery
        square_rect.left = x
        self.initials_surf.blit(square, square_rect)

    def render_total(self, score):
        dest = self.total_surf
        dest.fill(self.get_color())
        if score is None:
            return
        text = self.build_time_string(score.total)
        size = self.get_configuration()["scoreboard-total-size"]
        rend = Font(self, size).render(text, True, self.get_text_color(),
                                       self.get_color())
        rect = rend.get_rect()
        rect.center = dest.get_rect().center
        dest.blit(rend, rect)

    def build_time_string(self, time):
        return "%i:%02i" % divmod(int(time), 60)

    def get_blank_time(self):
        return self.get_blank_char()

    def render_split(self, index, time):
        dest = self.split_surfs[index]
        dest.fill(self.get_color())
        if time is None:
            return
        text = self.build_time_string(time)
        size = self.get_configuration()["scoreboard-split-size"]
        rend = Font(self, size).render(text, True, self.get_text_color(),
                                       self.get_color())
        rect = rend.get_rect()
        rect.center = dest.get_rect().center
        dest.blit(rend, rect)

    def update(self):
        self.clear()
        self.draw()

    def clear(self):
        self.fill(self.get_color())

    def draw(self):
        self.blit(self.rank_surf, self.rank_surf_r)
        self.blit(self.initials_surf, self.initials_surf_r)
        self.blit(self.total_surf, self.total_surf_r)
        for ii, surf in enumerate(self.split_surfs):
            self.blit(surf, self.split_surfs_rs[ii])
        self.parent.blit(self, self.rect)
216.73.216.215
216.73.216.215
216.73.216.215
 
July 18, 2022


A new era ‼

Our infrastructure has recently upgraded ‼

Nugget Communications Bureau 👍

You've never emailed like this before ‼

Roundcube

Webmail software for reading and sending email from @nugget.fun and @shampoo.ooo addresses.

Mailman3

Email discussion lists, modernized with likes and emojis. It can be used for announcements and newsletters in addition to discussions. See lists for Picture Processing or Scrapeboard. Nowadays, people use Discord, but you really don't have to!

FreshRSS

With this hidden in plain sight, old technology, even regular people like you and me can start our own newspaper or social media feed.

Nugget Streaming Media 👍

The content you crave ‼

HLS

A live streaming, video format based on M3U playlists that can be played with HTML5.

RTMP

A plugin for Nginx can receive streaming video from ffmpeg or OBS and forward it as an RTMP stream to sites like Youtube and Twitch or directly to VLC.


Professional ‼

Nugget Productivity Suite 👍

Unleash your potential ‼

Kanboard

Virtual index cards you can use to gamify your daily grind.

Gitea

Grab whatever game code you want, share your edits, and report bugs.

Nugget Security 👍

The real Turing test ‼

Fail2ban

Banning is even more fun when it's automated.

Spamassassin

The documentation explains, "an email which mentions rolex watches, Viagra, porn, and debt all in one" will probably be considered spam.

GoAccess

Display HTTP requests in real time, so you can watch bots try to break into WordPress.

Nugget Entertainment Software 👍

The best in gaming entertainment ‼

Emoticon vs. Rainbow

With everything upgraded to the bleeding edge, this HTML4 game is running better than ever.


Zoom ‼

The game engine I've been working on, SPACE BOX, is now able to export to web, so I'm planning on turning nugget.fun into a games portal by releasing my games on it and adding an accounts system. The upgraded server and software will make it easier to create and maintain. I'm also thinking of using advertising and subscriptions to support the portal, so some of these services, like webmail or the RSS reader, may be offered to accounts that upgrade to a paid subscription.