init: mvp

This commit is contained in:
Arthur Khachaturov 2024-08-17 01:20:24 +03:00
commit e307989b9f
No known key found for this signature in database
GPG key ID: CAC2B7EB6DF45D55
20 changed files with 835 additions and 0 deletions

View file

@ -0,0 +1,41 @@
package boosts
type Item struct {
ID string `json:"id"`
Price int `json:"price"`
EarnPerTap int `json:"earnPerTap"`
MaxTaps int `json:"maxTaps"`
CooldownSeconds *int `json:"cooldownSeconds"`
TotalCooldownSeconds *int `json:"totalCooldownSeconds"`
Level int `json:"level"`
MaxTapsDelta int `json:"maxTapsDelta"`
EarnPerTapDelta int `json:"earnPerTapDelta"`
MaxLevel *int `json:"maxLevel,omitempty"`
}
func (i *Item) Tick() {
if i.TotalCooldownSeconds != nil && *i.TotalCooldownSeconds > 0 {
(*i.TotalCooldownSeconds)--
}
}
type Boosts []*Item
type Response struct {
Boosts `json:"boostsForBuy"`
}
func (b *Boosts) Tick() {
for _, el := range *b {
el.Tick()
}
}
func (b *Boosts) SelectById(id string) *Item {
for _, i := range *b {
if i.ID == id {
return i
}
}
return nil
}

View file

@ -0,0 +1,54 @@
package config
type Task struct {
ID string `json:"id"`
Link *string `json:"link"`
Reward int `json:"rewardCoins"`
Cycle Cycle `json:"periodicity"`
ChannelId *int `json:"channelId"`
}
type ClickerConfig struct {
MaxPassive int `json:"maxPassiveDtSeconds"`
Tasks []Task `json:"tasks"`
}
type DailyCipher struct {
Cipher string `json:"cipher"`
BonusCoins int `json:"bonusCoins"`
IsClaimed bool `json:"isClaimed"`
RemainSeconds int `json:"remainSeconds"`
}
type DailyKeys struct {
StartDate string `json:"startDate"`
LevelConfig string `json:"levelConfig"`
BonusKeys int `json:"bonusKeys"`
IsClaimed bool `json:"isClaimed"`
SecondsToNext int `json:"totalSecondsToNextAttempt"`
RemainToGuess float32 `json:"remainSecondsToGuess"`
RemainSeconds float32 `json:"remainSeconds"`
RemainToNext float32 `json:"remainSecondsToNextAttempt"`
}
type Response struct {
ClickerConfig ClickerConfig `json:"clickerConfig"`
DailyCipher DailyCipher `json:"dailyCipher"`
DailyKeys DailyKeys `json:"DailyKeysMiniGame"`
}
func (c *DailyCipher) Tick() {
c.RemainSeconds--
}
func (k *DailyKeys) Tick() {
k.RemainToGuess--
k.RemainToNext--
k.RemainSeconds--
k.SecondsToNext--
}
func (r *Response) Tick() {
r.DailyCipher.Tick()
r.DailyKeys.Tick()
}

View file

@ -0,0 +1,8 @@
package config
type Cycle string
const (
Repeatedly Cycle = "repeatedly"
Once Cycle = "once"
)

View file

@ -0,0 +1,12 @@
package config
import "encoding/base64"
func (c *DailyCipher) Decode() (string, error) {
enc, err := base64.StdEncoding.DecodeString(c.Cipher[:3] + c.Cipher[4:])
if err != nil {
return "", err
}
return string(enc), nil
}

View file

@ -0,0 +1,68 @@
package upgrades
import (
"encoding/json"
)
type Type string
const (
byUpgrade Type = "ByUpgrade"
referralCount Type = "ReferralCount"
moreReferralCount Type = "MoreReferralsCount"
subscribeTelegramChannel Type = "SubscribeTelegramChannel"
)
type Condition struct {
Type Type
ByUpgrade *ByUpgrade
ReferralCount *ReferralCount
MoreReferralCount *MoreReferralCount
SubscribeTelegramChannel *SubscribeTelegramChannel
}
type ByUpgrade struct {
Level int
UpgradeID string
}
type ReferralCount struct {
ReferralCount int
}
type MoreReferralCount struct {
MoreReferralCount int
}
type SubscribeTelegramChannel struct {
ChannelID int
Link string
}
func (c *Condition) UnmarshalJSON(d []byte) error {
type tmpStruct struct {
Type Type `json:"_type"`
ByUpgrade
ReferralCount
MoreReferralCount
SubscribeTelegramChannel
}
var tmp = new(tmpStruct)
if err := json.Unmarshal(d, tmp); err != nil {
return err
}
c.Type = tmp.Type
switch tmp.Type {
case byUpgrade:
c.ByUpgrade = &tmp.ByUpgrade
case referralCount:
c.ReferralCount = &tmp.ReferralCount
case moreReferralCount:
c.MoreReferralCount = &tmp.MoreReferralCount
case subscribeTelegramChannel:
c.SubscribeTelegramChannel = &tmp.SubscribeTelegramChannel
}
return nil
}

View file

@ -0,0 +1,37 @@
package upgrades
import (
"encoding/json"
)
func (u *Upgrades) RecurseUnavailable(item *Item) []*Item {
if item.IsAvailable || (item.Condition == nil || item.Condition.ByUpgrade == nil) {
return []*Item{item}
}
return append(u.RecurseUnavailable((*u)[item.Condition.ByUpgrade.UpgradeID]), item)
}
func (r *Response) UnmarshalJSON(data []byte) error {
type tempType Response
var temp *tempType = (*tempType)(r)
err := json.Unmarshal(data, temp)
if err != nil {
return err
}
r.Upgrades = make(Upgrades)
for _, i := range r.UpgradesArray {
r.Upgrades[i.ID] = i
}
return nil
}
func (r *Response) Tick() {
for _, e := range r.UpgradesArray {
e.Tick()
}
}

View file

@ -0,0 +1,76 @@
package upgrades
import "time"
type Item struct {
ID string `json:"id"`
Name string `json:"name"`
Price int `json:"price"`
ProfitPerHour int `json:"profitPerHour"`
Condition *Condition `json:"condition,omitempty"`
Section string `json:"section"`
Level int `json:"level"`
CurrentProfit int `json:"currentProfitPerHour"`
ProfitDelta int `json:"profitPerHourDelta"`
IsAvailable bool `json:"isAvailable"`
IsExpired bool `json:"isExpired"`
Cooldown *int `json:"cooldownSeconds"`
TotalCooldown *int `json:"totalCooldownSeconds"`
ReleaseAt *string `json:"releaseAt"`
ExpiresAt *string `json:"expiresAt"`
MaxLevel *int `json:"maxLevel"`
}
func (i *Item) Tick() {
if i.ExpiresAt != nil && !i.IsExpired && *i.ExpiresAt != "" {
expire_time, _ := time.Parse(time.RFC3339, *i.ExpiresAt)
if expire_time.Sub(time.Now()) < 0 {
i.IsExpired = true
}
}
if i.Cooldown != nil && *i.Cooldown > 0 {
(*i.Cooldown)--
}
}
type Section struct {
Name string `json:"section"`
IsAvailable bool `json:"isAvailable"`
}
type DailyCombo struct {
UpgradeIDs []string `json:"upgradeIds"`
BonusCoins int `json:"bonusCoins"`
IsClaimed bool `json:"isClaimed"`
RemainingSeconds int `json:"remainSeconds"`
}
type Upgrades map[string]*Item
type Response struct {
UpgradesArray []*Item `json:"upgradesForBuy"`
Upgrades Upgrades `json:"-"`
Sections []Section `json:"sections"`
DailyCombo DailyCombo `json:"dailyCombo"`
}
func (i *Item) PriceByLevel(level int) int {
return 0
}
func (i *Item) ProfitDeltaByLevel(level int) int {
return 0
}
func (i *Item) CooldownByLevel(level int) int {
return 0
}
// def profit_delta_by_level(self, level: int) -> int:
// return round(self.profit_per_hour_delta * 1.07 ** level)
//
// def price_by_level(self, level: int) -> int:
// return round(self.price * 1.05 ** ((level + 3) * level / 2))
//
// def cooldown_by_level(self, level: int) -> int:
// return self.cooldown_seconds * 2 ** level if self.cooldown_seconds else 0

View file

@ -0,0 +1,64 @@
package user
type Boost struct {
ID string `json:"id"`
Level int `json:"level"`
LastUpgradeTime int `json:"lastUpgradeAt"`
}
type Boosts struct {
BoostMaxTaps Boost `json:"boostMaxTaps"`
BoostEarnPerTap Boost `json:"boostEarnPerTap"`
BoostFullAvailableTaps Boost `json:"boostFullAvailableTaps"`
}
type Upgrade struct {
ID string `json:"id"`
Level int `json:"level"`
LastUpgradeAt int `json:"lastUpgradeAt"`
}
type StreakDays struct {
ID string `json:"id"`
CompletedAt string `json:"completedAt"`
Days int `json:"days"`
}
type Tasks struct {
StreakDays StreakDays `json:"streak_days"`
}
type ClickerUser struct {
ID string `json:"id"`
TotalCoins float32 `json:"totalCoins"`
Balance float32 `json:"balanceCoins"`
Level int `json:"level"`
AvailableTaps int `json:"availableTaps"`
Boosts Boosts `json:"boosts"`
Tasks Tasks `json:"tasks"`
ReferralsCount int `json:"referralsCount"`
MaxTaps int `json:"maxTaps"`
EarnPerTap int `json:"earnPerTap"`
PassivePerSecond float32 `json:"earnPassivePerSec"`
PassivePerHour float32 `json:"earnPassivePerHour"`
RecoverPerSecond int `json:"tapsRecoverPerSec"`
CreatedAt string `json:"createdAt"`
BalanceTickets int `json:"balanceTickets"`
TotalKeys int `json:"totalKeys"`
BalanceKeys int `json:"balanceKeys"`
}
func (u *ClickerUser) Tick() {
if u.AvailableTaps+u.RecoverPerSecond < u.MaxTaps {
u.AvailableTaps += u.RecoverPerSecond
} else {
u.AvailableTaps = u.MaxTaps
}
u.Balance += u.PassivePerSecond
u.TotalCoins += u.PassivePerSecond
}
type Response struct {
ClickerUser `json:"clickerUser"`
}