').attr('id',"levelup-user-"+idName).addClass('levelup-user pure-u-1 pure-u-md-10-24 pure-u-lg-6-24 pure-u-xl-5-24').attr('data-username',userName));
var userNameSpan = B("
").attr('id','levelup-user-'+idName+'-name');
userNameSpan.addClass('levelup-username');
var levelDiv = B("").attr('id','levelup-user-'+idName+'-level');
diff --git a/levelup_model.go b/levelup_model.go
index e2f5ace..4d431d7 100644
--- a/levelup_model.go
+++ b/levelup_model.go
@@ -66,3 +66,28 @@ func getAllNonLevelUpStats(user string) map[string]int {
closeDatabase()
return ret
}
+
+func getAllUserAcheivements(user string) map[string]int {
+ openDatabase()
+ ret := make(map[string]bool)
+ db.Update(func(tx *bolt.Tx) error {
+ var b, uB, uSB *bolt.Bucket
+ var err error
+
+ b = tx.Bucket([]byte("users"))
+ if b == nil {
+ return fmt.Errorf("Unable to open 'users' bucket")
+ }
+ if uB = b.Bucket([]byte(user)); uB != nil {
+ if uSB = uB.Bucket([]byte("achievements")); uSB != nil {
+ return uSB.ForEach(func(k, v []byte) error {
+ ret[string(k)] = (string(v) == "true")
+ return nil
+ })
+ }
+ }
+ return err
+ })
+ closeDatabase()
+ return ret
+}
diff --git a/processor_levelupachieve.go b/processor_levelupachieve.go
index 8adee02..36be6b6 100644
--- a/processor_levelupachieve.go
+++ b/processor_levelupachieve.go
@@ -2,6 +2,19 @@ package main
import "net/http"
+type levelUpAchievement struct {
+ GetName func() string
+ GetText func() string
+ GetKeyName func() string
+ // Processes the message, returns true if the achievement was triggered
+ ProcessMessage func(ustat *UserLevelUpStats) bool
+}
+
+func (achieve *levelUpAchievement) DoesUserHave(ustat *UserLevelUpStats) bool {
+ val, ok := ustat.Achievements[achieve.GetKeyName()]
+ if ustat.Achievements
+}
+
type levelUpAchieveStatProcessor struct {
Achievements []levelUpAchievement
}
@@ -16,47 +29,42 @@ func (p *levelUpAchieveStatProcessor) GetStatKeys() []string {
}
}
-func (p *levelUpAcheiveStatProcessor) Initialize() {
- // TODO: Set up achievements
- p.Achievements = append(p.Achievements, levelUpAchievement{
- GetName: func() string {
- },
- GetText: func() string {
- },
- DoesUserHave: func(uID string) bool {
- },
- ProcessMessage: func(m *Message) bool {
- },
- })
-
-}
-
-type levelUpAchievement struct {
- GetName func() string
- GetText func() string
- // Returns whether the user already has this achievement
- DoesUserHave func(uID string) bool
- // Processes the message, returns true if the achievement was triggered
- ProcessMessage func(m *Message) bool
+// UserLevelUpStats is just a struct for caching user data...
+// This processor needs to crunch a lot of numbers, this should make
+// it quicker/easier
+type UserLevelUpStats struct {
+ Name string
+ Xp int
+ ChannelStats map[string]int
+ OtherStats map[string]int
+ Achievements map[string]bool
+ CurrentMsg *Message
+ CurrentCh *Channel
}
func (p *levelUpAchieveStatProcessor) ProcessMessage(m *Message) {
- type UserLevelUpStats struct {
- Name string
- Xp int
- ChannelStats map[string]int
- OtherStats map[string]int
- }
var u *User
var err error
if u, err = getUserInfo(m.User); err != nil {
return
}
- userStat := UserLevelUpStats{Name: u.Name}
+ userStat := UserLevelUpStats{Name: u.Name, CurrentMsg: m}
userStat.Xp, _ = getUserStat(u.ID, "levelup-xp")
userStat.ChannelStats = getAllLevelUpChannelXp(u.ID)
userStat.OtherStats = getAllNonLevelUpStats(u.ID)
+ userStat.Achievements = getAllUserAchievements(u.ID)
+ chnl, err := getChannelInfo(m.Channel)
+ if err == nil {
+ userStat.CurrentCh = chnl
+ }
+
+ for _, achieve := range p.Achievements {
+ if !achieve.DoesUserHave(userStat) {
+ // User doesn't already have this achieve, let it process the message
+ achieve.ProcessMessage(userStat)
+ }
+ }
}
func (p *levelUpAchieveStatProcessor) ProcessAdminMessage(m *Message) {}
func (p *levelUpAchieveStatProcessor) ProcessBotMessage(m *Message) {}
@@ -100,5 +108,138 @@ func (wm *levelUpAchieveWebModule) GetBottomMenuEntries() []menuItem {
func (wm *levelUpAchieveWebModule) handleLevelUpAchieveGeneral(w http.ResponseWriter, req *http.Request) {
initRequest(w, req)
- setMenuItemActive("Achieve GET!")
+ //setMenuItemActive("Achieve GET!")
+}
+
+/*
+ * Achieve Stat Processor Initialization
+ * It's down here because it's so long what with all
+ * of it's achievements and such.
+ */
+func (p *levelUpAcheiveStatProcessor) Initialize() {
+ // TODO: Set up achievements
+ p.Achievements = append(p.Achievements,
+ // Early Bird Achievement
+ levelUpAchievement{
+ GetName: func() string {
+ return "Early Bird"
+ },
+ GetText: func() string {
+ return "You seem to enjoy chatting before 7 AM"
+ },
+ GetKeyName: func() string {
+ return "levelup-achieve-earlybird"
+ },
+ ProcessMessage: func(u *userStat) bool {
+ // TODO: What condition makes this happen?
+ if m.Time.Hour() > 3 && m.Time.Hour() < 7 {
+ numMsgs := 0
+ numMsgs = numMsgs + userStat.OtherStats["message-hour-04"]
+ numMsgs = numMsgs + userStat.OtherStats["message-hour-05"]
+ numMsgs = numMsgs + userStat.OtherStats["message-hour-06"]
+ /*
+ if chnl.Name == "random" {
+ addUserStat(m.User, "levelup-xp", 1)
+ } else if chnl.Name == "general" {
+ addUserStat(m.User, "levelup-xp", 2)
+ } else {
+ addUserStat(m.User, "levelup-xp", 3)
+ addUserStat(m.User, "levelup-xp-"+chnl.Name, 1)
+ }
+ */
+ }
+ return false
+ },
+ },
+ )
+
+ p.Achievements = append(p.Achievements,
+ // Night Owl Achievement
+ levelUpAchievement{
+ GetName: func() string {
+ return "Night Owl"
+ },
+ GetText: func() string {
+ return "You seem to enjoy chatting after 12 AM"
+ },
+ GetKeyName: func() string {
+ return "levelup-achieve-nightowl"
+ },
+ ProcessMessage: func(u *userStat) bool {
+ // TODO: What condition makes this happen?
+ },
+ },
+ )
+
+ p.Achievements = append(p.Achievements,
+ // Around the Clock Achievement
+ levelUpAchievement{
+ GetName: func() string {
+ return "Around the Clock"
+ },
+ GetText: func() string {
+ return "You have sent at least one message in every hour of the day"
+ },
+ GetKeyName: func() string {
+ return "levelup-achieve-aroundtheclock"
+ },
+ ProcessMessage: func(u *userStat) bool {
+ // TODO: What condition makes this happen?
+ },
+ },
+ )
+
+ p.Achievements = append(p.Achievements,
+ // Beginner Achievement
+ levelUpAchievement{
+ GetName: func() string {
+ return "Beginner"
+ },
+ GetText: func() string {
+ return "Get on the XP Chart"
+ },
+ GetKeyName: func() string {
+ return "levelup-achieve-beginner"
+ },
+ ProcessMessage: func(u *userStat) bool {
+ // TODO: What condition makes this happen?
+ },
+ },
+ )
+
+ p.Achievements = append(p.Achievements,
+ // Experienced Achievement
+ levelUpAchievement{
+ GetName: func() string {
+ return "Experienced"
+ },
+ GetText: func() string {
+ return "Reach level 5"
+ },
+ GetKeyName: func() string {
+ return "levelup-achieve-experienced"
+ },
+ ProcessMessage: func(u *userStat) bool {
+ // TODO: What condition makes this happen?
+ },
+ },
+ )
+
+ p.Achievements = append(p.Achievements,
+ // Super Advanced! Achievement
+ levelUpAchievement{
+ GetName: func() string {
+ return "Super Advanced!"
+ },
+ GetText: func() string {
+ return "Reach level 10"
+ },
+ GetKeyName: func() string {
+ return "levelup-achieve-superadvanced"
+ },
+ ProcessMessage: func(u *userStat) bool {
+ // TODO: What condition makes this happen?
+ },
+ },
+ )
}
diff --git a/statbot.go b/statbot.go
index 7e2a749..31ec042 100644
--- a/statbot.go
+++ b/statbot.go
@@ -9,6 +9,7 @@ import (
const programName = "statbot"
+// Message Processors are interfaces for interacting.
type messageProcessor interface {
GetName() string
GetHelp() string
@@ -25,6 +26,7 @@ type messageProcessor interface {
var messageProcessors []messageProcessor
+// Message Processors are interfaces for accumulating statistics.
type statProcessor interface {
GetName() string
GetStatKeys() []string