init
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| WoWChatLog.txt | ||||
| .idea | ||||
							
								
								
									
										35
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	b, err := os.ReadFile("WoWChatLog.txt") | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Strip carriage returns because Windows is retarded | ||||
| 	b = bytes.ReplaceAll(b, []byte("\r"), []byte("")) | ||||
|  | ||||
| 	lines := strings.Split(string(b), "\n") | ||||
|  | ||||
| 	games, err := parseGames(lines) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	for _, game := range games { | ||||
| 		j, err := json.Marshal(game) | ||||
| 		if err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
| 		fmt.Println(string(j)) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										143
									
								
								parser.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								parser.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,143 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	gameTypeUnknown = iota | ||||
| 	gameTypeClassic | ||||
| ) | ||||
|  | ||||
| type Game struct { | ||||
| 	Timestamp time.Time `json:"timestamp"` | ||||
| 	GameType  int       `json:"game_type"` | ||||
| 	Wager     int       `json:"wager"` | ||||
| 	Winner    string    `json:"winner"` | ||||
| 	Loser     string    `json:"loser"` | ||||
| 	HighRoll  int       `json:"high_roll"` | ||||
| 	LowRoll   int       `json:"low_roll"` | ||||
| 	Payout    int       `json:"payout"` | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	reTimeStamp = regexp.MustCompile(`(\d/\d \d+:\d+:\d+.\d+)`) | ||||
| 	reGameStart = regexp.MustCompile(`WoWGoldGambler: A new game has been started`) | ||||
| 	reWager     = regexp.MustCompile(`Game Mode - ([A-Z]+) - Wager - ([\d,]+)g$`) | ||||
| 	reSignup    = regexp.MustCompile(`([\p{L}']+)-[\p{L}'0-9]+: (1|-1)`) | ||||
| 	reRoll      = regexp.MustCompile(`([\p{L}']+) rolls (\d+) \(1-(\d+)\)$`) | ||||
| 	reEnd       = regexp.MustCompile(`([\p{L}']+) owes ([\p{L}']+) ([\d,]+) gold!`) | ||||
| ) | ||||
|  | ||||
| func parseGames(lines []string) ([]Game, error) { | ||||
| 	games := make([]Game, 0) | ||||
| 	var err error | ||||
|  | ||||
| 	i := 0 | ||||
| 	for i < len(lines) { | ||||
| 		if reGameStart.MatchString(lines[i]) { | ||||
| 			var game Game | ||||
| 			game, i, err = parse(lines, i) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			games = append(games, game) | ||||
| 		} | ||||
| 		i++ | ||||
| 	} | ||||
|  | ||||
| 	return games, nil | ||||
| } | ||||
|  | ||||
| func parse(lines []string, i int) (Game, int, error) { | ||||
| 	var ( | ||||
| 		g   Game | ||||
| 		err error | ||||
| 	) | ||||
|  | ||||
| 	// Timestamp | ||||
| 	ts := reTimeStamp.FindString(lines[i]) | ||||
| 	if ts == "" { | ||||
| 		return g, i, fmt.Errorf("failed to extract timestamp from %s", lines[i]) | ||||
| 	} | ||||
| 	g.Timestamp, err = time.Parse("1/2 15:04:05.000", ts) | ||||
| 	if err != nil { | ||||
| 		return g, i, err | ||||
| 	} | ||||
|  | ||||
| 	// Wager | ||||
| 	i++ | ||||
| 	matches := reWager.FindStringSubmatch(lines[i]) | ||||
| 	switch matches[1] { | ||||
| 	case "CLASSIC": | ||||
| 		g.GameType = gameTypeClassic | ||||
| 	default: | ||||
| 		g.GameType = gameTypeUnknown | ||||
| 	} | ||||
| 	g.Wager, err = strconv.Atoi(strings.ReplaceAll(matches[2], ",", "")) | ||||
| 	if err != nil { | ||||
| 		return g, i, err | ||||
| 	} | ||||
|  | ||||
| 	// Registration | ||||
| 	for { | ||||
| 		if strings.Contains(lines[i], "Registration has ended") { | ||||
| 			break | ||||
| 		} | ||||
| 		i++ | ||||
| 	} | ||||
|  | ||||
| 	// Capture Rolls | ||||
| 	rolls := make(map[string]int) | ||||
| 	for { | ||||
| 		if reEnd.MatchString(lines[i]) { | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		rollMatches := reRoll.FindStringSubmatch(lines[i]) | ||||
| 		if rollMatches == nil { | ||||
| 			i++ | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		v, err := strconv.Atoi(rollMatches[3]) | ||||
| 		if err != nil { | ||||
| 			return g, i, err | ||||
| 		} | ||||
| 		if v != g.Wager { | ||||
| 			i++ | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Ignore extra rolls | ||||
| 		if _, ok := rolls[rollMatches[1]]; !ok { | ||||
| 			val, err := strconv.Atoi(rollMatches[2]) | ||||
| 			if err != nil { | ||||
| 				return g, i, err | ||||
| 			} | ||||
| 			rolls[rollMatches[1]] = val | ||||
| 		} | ||||
|  | ||||
| 		i++ | ||||
| 	} | ||||
|  | ||||
| 	endMatches := reEnd.FindStringSubmatch(lines[i]) | ||||
| 	p := strings.ReplaceAll(endMatches[3], ",", "") | ||||
| 	payout, err := strconv.Atoi(p) | ||||
| 	if err != nil { | ||||
| 		return g, i, err | ||||
| 	} | ||||
| 	g.Payout = payout | ||||
|  | ||||
| 	g.Winner = endMatches[2] | ||||
| 	g.HighRoll = rolls[g.Winner] | ||||
|  | ||||
| 	g.Loser = endMatches[1] | ||||
| 	g.LowRoll = rolls[g.Loser] | ||||
|  | ||||
| 	return g, i, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user