252 lines
6.6 KiB
Go
252 lines
6.6 KiB
Go
package voiceroomrocket
|
|
|
|
import (
|
|
"encoding/json"
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
type energyRuleConfig struct {
|
|
GoldRatio float64 `json:"goldRatio"`
|
|
AllowedGiftTypes []string `json:"allowedGiftTypes"`
|
|
AllowedGiftTabs []string `json:"allowedGiftTabs"`
|
|
BlockedGiftTypes []string `json:"blockedGiftTypes"`
|
|
BlockedGiftTabs []string `json:"blockedGiftTabs"`
|
|
GiftRules []giftEnergyRule `json:"giftRules"`
|
|
GiftTabRules []giftTabEnergyRule `json:"giftTabRules"`
|
|
}
|
|
|
|
type giftEnergyRule struct {
|
|
GiftID flexibleInt64 `json:"giftId"`
|
|
GiftIDs []flexibleInt64 `json:"giftIds"`
|
|
Enabled *bool `json:"enabled"`
|
|
Allow *bool `json:"allow"`
|
|
Energy int64 `json:"energy"`
|
|
EnergyPerUnit int64 `json:"energyPerUnit"`
|
|
Ratio float64 `json:"ratio"`
|
|
}
|
|
|
|
type giftTabEnergyRule struct {
|
|
GiftTab string `json:"giftTab"`
|
|
GiftTabs []string `json:"giftTabs"`
|
|
Enabled *bool `json:"enabled"`
|
|
Allow *bool `json:"allow"`
|
|
Energy int64 `json:"energy"`
|
|
EnergyPerUnit int64 `json:"energyPerUnit"`
|
|
Ratio float64 `json:"ratio"`
|
|
}
|
|
|
|
func resolveGiftEnergy(event giftEvent, snapshot configSnapshot) (int64, string) {
|
|
rule, err := parseEnergyRule(snapshot.EnergyRuleJSON)
|
|
if err != nil {
|
|
return 0, "invalid_energy_rule"
|
|
}
|
|
base := calculateBaseGiftEnergy(event)
|
|
if base <= 0 {
|
|
return 0, "zero_energy"
|
|
}
|
|
if custom, ok, reason := applyGiftIDRule(event, base, rule); ok || reason != "" {
|
|
return custom, reason
|
|
}
|
|
if !isAllowedByGiftTypeAndTab(event, rule) {
|
|
return 0, "unsupported_gift"
|
|
}
|
|
if custom, ok, reason := applyGiftTabRule(event, base, rule); ok || reason != "" {
|
|
return custom, reason
|
|
}
|
|
ratio := rule.GoldRatio
|
|
if ratio <= 0 {
|
|
ratio = 1
|
|
}
|
|
energy := int64(math.Floor(float64(base) * ratio))
|
|
if energy <= 0 {
|
|
return 0, "zero_energy"
|
|
}
|
|
return energy, ""
|
|
}
|
|
|
|
func parseEnergyRule(raw string) (energyRuleConfig, error) {
|
|
raw = strings.TrimSpace(raw)
|
|
if raw == "" || raw == "null" || raw == "{}" {
|
|
return energyRuleConfig{}, nil
|
|
}
|
|
var rule energyRuleConfig
|
|
if err := json.Unmarshal([]byte(raw), &rule); err != nil {
|
|
return energyRuleConfig{}, err
|
|
}
|
|
return rule, nil
|
|
}
|
|
|
|
func applyGiftIDRule(event giftEvent, base int64, rule energyRuleConfig) (int64, bool, string) {
|
|
giftID := event.GiftConfig.ID.Int64()
|
|
if giftID <= 0 || len(rule.GiftRules) == 0 {
|
|
return 0, false, ""
|
|
}
|
|
for _, item := range rule.GiftRules {
|
|
if !giftRuleMatches(item, giftID) {
|
|
continue
|
|
}
|
|
if item.Enabled != nil && !*item.Enabled {
|
|
return 0, true, "gift_rule_disabled"
|
|
}
|
|
if item.Allow != nil && !*item.Allow {
|
|
return 0, true, "gift_rule_blocked"
|
|
}
|
|
quantity := normalizedGiftQuantity(event)
|
|
acceptUserSize := normalizedAcceptUserSize(event)
|
|
if item.Energy > 0 {
|
|
return item.Energy * quantity * acceptUserSize, true, ""
|
|
}
|
|
if item.EnergyPerUnit > 0 {
|
|
return item.EnergyPerUnit * quantity * acceptUserSize, true, ""
|
|
}
|
|
if item.Ratio > 0 {
|
|
energy := int64(math.Floor(float64(base) * item.Ratio))
|
|
if energy <= 0 {
|
|
return 0, true, "zero_energy"
|
|
}
|
|
return energy, true, ""
|
|
}
|
|
return base, true, ""
|
|
}
|
|
return 0, false, ""
|
|
}
|
|
|
|
func applyGiftTabRule(event giftEvent, base int64, rule energyRuleConfig) (int64, bool, string) {
|
|
giftTab := normalizeGiftToken(event.GiftConfig.GiftTab)
|
|
if giftTab == "" || len(rule.GiftTabRules) == 0 {
|
|
return 0, false, ""
|
|
}
|
|
for _, item := range rule.GiftTabRules {
|
|
if !giftTabRuleMatches(item, giftTab) {
|
|
continue
|
|
}
|
|
if item.Enabled != nil && !*item.Enabled {
|
|
return 0, true, "gift_tab_rule_disabled"
|
|
}
|
|
if item.Allow != nil && !*item.Allow {
|
|
return 0, true, "gift_tab_rule_blocked"
|
|
}
|
|
quantity := normalizedGiftQuantity(event)
|
|
acceptUserSize := normalizedAcceptUserSize(event)
|
|
if item.Energy > 0 {
|
|
return item.Energy * quantity * acceptUserSize, true, ""
|
|
}
|
|
if item.EnergyPerUnit > 0 {
|
|
return item.EnergyPerUnit * quantity * acceptUserSize, true, ""
|
|
}
|
|
if item.Ratio > 0 {
|
|
energy := int64(math.Floor(float64(base) * item.Ratio))
|
|
if energy <= 0 {
|
|
return 0, true, "zero_energy"
|
|
}
|
|
return energy, true, ""
|
|
}
|
|
return base, true, ""
|
|
}
|
|
return 0, false, ""
|
|
}
|
|
|
|
func giftRuleMatches(rule giftEnergyRule, giftID int64) bool {
|
|
if rule.GiftID.Int64() == giftID {
|
|
return true
|
|
}
|
|
for _, id := range rule.GiftIDs {
|
|
if id.Int64() == giftID {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func giftTabRuleMatches(rule giftTabEnergyRule, giftTab string) bool {
|
|
if normalizeGiftToken(rule.GiftTab) == giftTab {
|
|
return true
|
|
}
|
|
for _, tab := range rule.GiftTabs {
|
|
if normalizeGiftToken(tab) == giftTab {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isAllowedByGiftTypeAndTab(event giftEvent, rule energyRuleConfig) bool {
|
|
giftType := normalizeGiftToken(event.GiftConfig.Type)
|
|
giftTab := normalizeGiftToken(event.GiftConfig.GiftTab)
|
|
if containsGiftToken(rule.BlockedGiftTypes, giftType) || containsGiftToken(rule.BlockedGiftTabs, giftTab) {
|
|
return false
|
|
}
|
|
if len(rule.AllowedGiftTypes) > 0 && !containsGiftToken(rule.AllowedGiftTypes, giftType) {
|
|
return false
|
|
}
|
|
if len(rule.AllowedGiftTabs) > 0 && !containsGiftToken(rule.AllowedGiftTabs, giftTab) {
|
|
return false
|
|
}
|
|
if isDefaultBlockedGiftToken(giftType) || isDefaultBlockedGiftToken(giftTab) {
|
|
return false
|
|
}
|
|
if giftType == "" {
|
|
return false
|
|
}
|
|
return giftType == rewardTypeGold
|
|
}
|
|
|
|
func containsGiftToken(list []string, token string) bool {
|
|
token = normalizeGiftToken(token)
|
|
if token == "" {
|
|
return false
|
|
}
|
|
for _, item := range list {
|
|
if normalizeGiftToken(item) == token {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isDefaultBlockedGiftToken(token string) bool {
|
|
switch normalizeGiftToken(token) {
|
|
case "DIAMOND", "LUCKY", "ACTIVITY", "CP", "MAGIC", "FREE":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func normalizeGiftToken(value string) string {
|
|
return strings.ToUpper(strings.TrimSpace(value))
|
|
}
|
|
|
|
func calculateBaseGiftEnergy(event giftEvent) int64 {
|
|
if actual := event.GiftValue.ActualAmount.Int64(); actual > 0 {
|
|
return actual
|
|
}
|
|
quantity := normalizedGiftQuantity(event)
|
|
giftCandy := event.GiftConfig.GiftCandy.Int64()
|
|
if giftCandy <= 0 {
|
|
return 0
|
|
}
|
|
return giftCandy * quantity * normalizedAcceptUserSize(event)
|
|
}
|
|
|
|
func calculateRawEnergy(event giftEvent) int64 {
|
|
return calculateBaseGiftEnergy(event)
|
|
}
|
|
|
|
func normalizedGiftQuantity(event giftEvent) int64 {
|
|
quantity := event.Quantity.Int64()
|
|
if quantity <= 0 {
|
|
return 1
|
|
}
|
|
return quantity
|
|
}
|
|
|
|
func normalizedAcceptUserSize(event giftEvent) int64 {
|
|
acceptUserSize := int64(countDistinctAcceptUsers(event.Accepts))
|
|
if acceptUserSize <= 0 {
|
|
return 1
|
|
}
|
|
return acceptUserSize
|
|
}
|