Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zJiaJun committed Aug 23, 2024
1 parent 70ac949 commit 8f93752
Show file tree
Hide file tree
Showing 35 changed files with 1,492 additions and 714 deletions.
36 changes: 36 additions & 0 deletions assets/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
html,
body {
overflow-x: hidden; /* Prevent scroll on narrow devices */
}

body {
padding-top: 56px;
}

@media (max-width: 991.98px) {
.offcanvas-collapse {
position: fixed;
top: 56px; /* Height of navbar */
bottom: 0;
left: 100%;
width: 100%;
padding-right: 1rem;
padding-left: 1rem;
overflow-y: auto;
visibility: hidden;
background-color: #343a40;
transition: transform .3s ease-in-out, visibility .3s ease-in-out;
}
.offcanvas-collapse.open {
visibility: visible;
transform: translateX(-100%);
}
}

.bg-purple {
background-color: #6f42c1;
}

.cookie-popover {
--bs-popover-max-width: 500px;
}
Binary file added assets/favicon.ico
Binary file not shown.
10 changes: 10 additions & 0 deletions assets/js/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const instance = axios.create({
baseURL: 'http://localhost:8070',
timeout: 10000,
headers: {'Content-Type':'application/json; charset=UTF-8'}
});





33 changes: 13 additions & 20 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,29 @@ import (
"flag"
"github.com/zJiajun/warmane/engine"
"github.com/zJiajun/warmane/logger"
"github.com/zJiajun/warmane/route"
"net"
"os"
"sync"
)

var goflag = flag.NewFlagSet("warmane", flag.ExitOnError)
var (
config string
points bool
trade bool
keepSession bool
)

var port string

func init() {
goflag.StringVar(&config, "c", "config.yml", "Configuration file")
goflag.BoolVar(&points, "p", false, "Run daily collect points")
goflag.BoolVar(&trade, "t", false, "Run scraper trade data")
goflag.BoolVar(&keepSession, "k", false, "Run keep session job")
goflag.StringVar(&port, "p", "8070", "Port to listen on")
goflag.Parse(os.Args[1:])
}

var onceMap = make(map[int]sync.Once)

func main() {
logger.Info("Main engine start")
e := engine.New(config)
if points {
e.RunDailyPoints()
}
if trade {
e.RunTradeData()
}
if keepSession {
e.KeepSession()
e := engine.New()
r := route.New(e)
addr := net.JoinHostPort("", port)
if err := r.Run(addr); err != nil {
logger.Fatal(err)
}
logger.Info("Main engine finish")
}
2 changes: 1 addition & 1 deletion engine/internal/pair.go → common/pair.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package internal
package common

type Pair[T, U any] struct {
Left T
Expand Down
8 changes: 8 additions & 0 deletions constant/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ const (
LogoutUrl = AccountUrl + "/logout"
)

const WarmaneSiteKey = "6LfXRRsUAAAAAEApnVwrtQ7aFprn4naEcc05AZUR"
const captchaApiKey = ""

const (
ONLINE_STATUS = "online"
OFFLINE_STATUS = "offline"
)

var CookieFileName = func(name string) string {
return name + ".cookies"
}
Expand Down
169 changes: 169 additions & 0 deletions engine/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package engine

import (
"errors"
"github.com/gocolly/colly/v2"
"github.com/gocolly/colly/v2/storage"
"github.com/zJiajun/warmane/constant"
"github.com/zJiajun/warmane/logger"
"github.com/zJiajun/warmane/model/table"
"math/rand/v2"
"strings"
"sync"
"time"
)

func (e *Engine) ListAccount() ([]*table.Account, error) {
var account []*table.Account
if result := e.db.Find(&account); result.Error != nil {
return nil, result.Error
}
return account, nil
}

func (e *Engine) ListOnlineAccount() ([]*table.Account, error) {
var account []*table.Account
if result := e.db.Where("status = ?", constant.ONLINE_STATUS).Find(&account); result.Error != nil {
return nil, result.Error
}
return account, nil
}

func (e *Engine) CreateAccount(account *table.Account) (int64, error) {
if result := e.db.Create(account); result.Error != nil {
return 0, result.Error
} else {
return result.RowsAffected, nil
}
}

func (e *Engine) UpdateAccount(account *table.Account) (int64, error) {
if result := e.db.Model(&table.Account{}).Where("id = ?", account.ID).Updates(account); result.Error != nil {
return 0, result.Error
} else {
return result.RowsAffected, nil
}
}

func (e *Engine) DeleteAccount(accountId int64) (int64, error) {
if result := e.db.Delete(&table.Account{}, accountId); result.Error != nil {
return 0, result.Error
} else {
return result.RowsAffected, nil
}
}

var onceMap = make(map[int64]sync.Once)

func (e *Engine) CheckAccount(accountId int64) (bool, error) {
var account *table.Account
e.db.First(&account, accountId)
if err := e.validateCookiesKey(account.Cookies); err != nil {
return false, err
}
accountDetails := &table.AccountDetails{
AccountId: account.ID,
AccountName: account.AccountName,
}
if err := e.validAndFetchAccountInfo(account.AccountName, accountDetails); err != nil {
return false, err
}
if err := e.updateAccountInfo(account, accountDetails); err != nil {
return false, err
}
if _, ok := onceMap[accountId]; !ok {
e.keepingAccountOnline(accountId)
}
return true, nil
}

func (e *Engine) keepingAccountOnline(accountId int64) {
once, ok := onceMap[accountId]
if !ok {
onceMap[accountId] = sync.Once{}
}
once.Do(func() {
t := time.NewTicker(time.Duration(rand.IntN(12)) * time.Minute)
for {
select {
case <-t.C:
if _, err := e.CheckAccount(accountId); err != nil {
logger.Errorf("keeping account [%d] online error, reasion: %v", accountId, err)
}
}
}
})
}

func (e *Engine) validateCookiesKey(cookies string) error {
if cookies == "" {
return errors.New("Cookies not exist or account not exist")
}
httpCookies := storage.UnstringifyCookies(cookies)
for _, v := range constant.CookieKeys {
if !storage.ContainsCookie(httpCookies, v) {
return errors.New("Cookies is incorrect, key is missing: " + v)
}
}
return nil
}

func (e *Engine) validAndFetchAccountInfo(accountName string, accountDetails *table.AccountDetails) error {
isLogin, _ := false, false
c := e.getScraper(accountName).CloneCollector()
e.getScraper(accountName).SetRequestHeaders(c)
e.getScraper(accountName).DecodeResponse(c)
c.OnHTML("div.content-inner.left > table > tbody > tr:nth-child(2) > td", func(element *colly.HTMLElement) {
isLogin = strings.Contains(element.Text, accountName)
})
c.OnHTML("form[id='frmAuthenticate']", func(element *colly.HTMLElement) {
//isAuth = true
})

c.OnHTML(".myCoins", func(element *colly.HTMLElement) {
accountDetails.Coins = element.Text
})
c.OnHTML(".myPoints", func(element *colly.HTMLElement) {
accountDetails.Points = element.Text
})
c.OnHTML("div.content-inner.left > table > tbody > tr:nth-child(6) > td", func(element *colly.HTMLElement) {
accountDetails.Email = strings.TrimSpace(strings.Split(element.Text, ":")[1])
})
c.OnHTML("div.content-inner.right > table > tbody > tr:nth-child(2) > td", func(element *colly.HTMLElement) {
accountDetails.Status = strings.TrimSpace(strings.Split(element.Text, ":")[1])
})
c.OnHTML("div.content-inner.right > table > tbody > tr:nth-child(3) > td", func(element *colly.HTMLElement) {
accountDetails.DonationRank = strings.TrimSpace(strings.Split(element.Text, ":")[1])
})
c.OnHTML("div.content-inner.right > table > tbody > tr:nth-child(4) > td", func(element *colly.HTMLElement) {
accountDetails.ActivityRank = strings.TrimSpace(strings.Split(element.Text, ":")[1])
})
c.OnHTML("div.content-inner.right > table > tbody > tr:nth-child(5) > td", func(element *colly.HTMLElement) {
accountDetails.CommunityRank = strings.TrimSpace(strings.Split(element.Text, ":")[1])
})
c.OnHTML("div.content-inner.right > table > tbody > tr:nth-child(7) > td", func(element *colly.HTMLElement) {
accountDetails.JoinDate = strings.TrimSpace(strings.Split(element.Text, ":")[1])
})
c.OnHTML("div.content-inner.right > table > tbody > tr:nth-child(8) > td", func(element *colly.HTMLElement) {
accountDetails.LastSeen = strings.TrimSpace(strings.Split(element.Text, ":")[1])
})
if err := c.Visit(constant.AccountUrl); err != nil {
return err
}
if !isLogin {
return errors.New("Account can not login")
}
logger.Infof("Account [%s] login success, fetch account info", accountName)
return nil
}

func (e *Engine) updateAccountInfo(account *table.Account, accountDetails *table.AccountDetails) error {
result := e.db.Model(&table.Account{}).Where("id = ?", account.ID).Where("status = ?", constant.OFFLINE_STATUS).Update("status", constant.ONLINE_STATUS)
if result.Error != nil {
return result.Error
}
if err := e.addOrUpdateAccountDetails(accountDetails); err != nil {
return err
}
return nil
}
Loading

0 comments on commit 8f93752

Please sign in to comment.