mdb, cmd/horsebot: affinity details
This commit is contained in:
16
character.go
16
character.go
@@ -11,11 +11,19 @@ func (c Character) String() string {
|
|||||||
return c.Name
|
return c.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AffinityRelation holds precomputed affinity values for a pair or trio.
|
||||||
type AffinityRelation struct {
|
type AffinityRelation struct {
|
||||||
IDA int `json:"chara_a"`
|
IDA CharacterID `json:"chara_a"`
|
||||||
IDB int `json:"chara_b"`
|
IDB CharacterID `json:"chara_b"`
|
||||||
IDC int `json:"chara_c,omitzero"`
|
IDC CharacterID `json:"chara_c,omitzero"`
|
||||||
Affinity int `json:"affinity"`
|
Affinity int `json:"affinity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AffinityDetail holds a single affinity entry.
|
||||||
|
type AffinityDetail struct {
|
||||||
|
CharaID CharacterID `json:"chara_id"`
|
||||||
|
Relation uint16 `json:"relation"`
|
||||||
|
Affinity uint16 `json:"affinity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conversation describes a lobby conversation.
|
// Conversation describes a lobby conversation.
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ func main() {
|
|||||||
mux.Handle("GET /", httpmiddle.Compress(5)(http.FileServerFS(os.DirFS(public))))
|
mux.Handle("GET /", httpmiddle.Compress(5)(http.FileServerFS(os.DirFS(public))))
|
||||||
}
|
}
|
||||||
mux.Handle("GET /api/global/affinity", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.AffinitySummary)))
|
mux.Handle("GET /api/global/affinity", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.AffinitySummary)))
|
||||||
|
mux.Handle("GET /api/global/affinity-detail", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.AffinityDetail)))
|
||||||
mux.Handle("GET /api/global/character", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Characters)))
|
mux.Handle("GET /api/global/character", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Characters)))
|
||||||
mux.Handle("GET /api/global/conversation", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Conversations)))
|
mux.Handle("GET /api/global/conversation", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Conversations)))
|
||||||
mux.Handle("GET /api/global/race", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Races)))
|
mux.Handle("GET /api/global/race", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Races)))
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ var (
|
|||||||
characterSQL string
|
characterSQL string
|
||||||
//go:embed sql/affinity.sql
|
//go:embed sql/affinity.sql
|
||||||
affinitySQL string
|
affinitySQL string
|
||||||
|
//go:embed sql/affinity-detail.sql
|
||||||
|
affinityDetailSQL string
|
||||||
//go:embed sql/uma.sql
|
//go:embed sql/uma.sql
|
||||||
umaSQL string
|
umaSQL string
|
||||||
//go:embed sql/conversation.sql
|
//go:embed sql/conversation.sql
|
||||||
@@ -35,14 +37,25 @@ func Characters(ctx context.Context, db *sqlitex.Pool) ([]horse.Character, error
|
|||||||
func AffinitySummary(ctx context.Context, db *sqlitex.Pool) ([]horse.AffinityRelation, error) {
|
func AffinitySummary(ctx context.Context, db *sqlitex.Pool) ([]horse.AffinityRelation, error) {
|
||||||
return load(ctx, db, nil, affinitySQL, func(s *sqlite.Stmt) horse.AffinityRelation {
|
return load(ctx, db, nil, affinitySQL, func(s *sqlite.Stmt) horse.AffinityRelation {
|
||||||
return horse.AffinityRelation{
|
return horse.AffinityRelation{
|
||||||
IDA: s.ColumnInt(0),
|
IDA: horse.CharacterID(s.ColumnInt(0)),
|
||||||
IDB: s.ColumnInt(1),
|
IDB: horse.CharacterID(s.ColumnInt(1)),
|
||||||
IDC: s.ColumnInt(2),
|
IDC: horse.CharacterID(s.ColumnInt(2)),
|
||||||
Affinity: s.ColumnInt(3),
|
Affinity: s.ColumnInt(3),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AffinityDetail gets all individual affinity group entries.
|
||||||
|
func AffinityDetail(ctx context.Context, db *sqlitex.Pool) ([]horse.AffinityDetail, error) {
|
||||||
|
return load(ctx, db, nil, affinityDetailSQL, func(s *sqlite.Stmt) horse.AffinityDetail {
|
||||||
|
return horse.AffinityDetail{
|
||||||
|
CharaID: horse.CharacterID(s.ColumnInt(0)),
|
||||||
|
Relation: uint16(s.ColumnInt(1)),
|
||||||
|
Affinity: uint16(s.ColumnInt(2)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Umas retrieves all trainable Uma variants.
|
// Umas retrieves all trainable Uma variants.
|
||||||
func Umas(ctx context.Context, db *sqlitex.Pool) ([]horse.Uma, error) {
|
func Umas(ctx context.Context, db *sqlitex.Pool) ([]horse.Uma, error) {
|
||||||
return load(ctx, db, make([]horse.Uma, 0, 128), umaSQL, func(s *sqlite.Stmt) horse.Uma {
|
return load(ctx, db, make([]horse.Uma, 0, 128), umaSQL, func(s *sqlite.Stmt) horse.Uma {
|
||||||
|
|||||||
@@ -44,6 +44,107 @@ func TestAffinitySummary(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAffinityDetail(t *testing.T) {
|
||||||
|
db := testdb(t.Context(), "file:TestAffinityDetail?mode=memory&cache=shared", characterSQL)
|
||||||
|
got, err := mdb.AffinityDetail(t.Context(), db)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
want := []horse.AffinityDetail{
|
||||||
|
{CharaID: 1001, Relation: 103, Affinity: 2},
|
||||||
|
{CharaID: 1001, Relation: 202, Affinity: 2},
|
||||||
|
{CharaID: 1001, Relation: 301, Affinity: 2},
|
||||||
|
{CharaID: 1001, Relation: 401, Affinity: 2},
|
||||||
|
{CharaID: 1001, Relation: 502, Affinity: 2},
|
||||||
|
{CharaID: 1001, Relation: 510, Affinity: 2},
|
||||||
|
{CharaID: 1001, Relation: 2001, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2102, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2301, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2406, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2506, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2510, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2516, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2519, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2601, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2603, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2811, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 2903, Affinity: 7},
|
||||||
|
{CharaID: 1001, Relation: 3003, Affinity: 7},
|
||||||
|
{CharaID: 1001, Relation: 3004, Affinity: 7},
|
||||||
|
{CharaID: 1001, Relation: 3101, Affinity: 7},
|
||||||
|
{CharaID: 1001, Relation: 3205, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 7003, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 7004, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 7005, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 7006, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 7007, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8001, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8002, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8003, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8004, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8005, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8006, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8007, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8008, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8009, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8010, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8011, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8012, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8013, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8014, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8015, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8016, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8443, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8479, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8511, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8536, Affinity: 1},
|
||||||
|
{CharaID: 1001, Relation: 8640, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 104, Affinity: 2},
|
||||||
|
{CharaID: 1002, Relation: 202, Affinity: 2},
|
||||||
|
{CharaID: 1002, Relation: 301, Affinity: 2},
|
||||||
|
{CharaID: 1002, Relation: 402, Affinity: 2},
|
||||||
|
{CharaID: 1002, Relation: 2001, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 2406, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 2512, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 2601, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 2603, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 2810, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 2901, Affinity: 7},
|
||||||
|
{CharaID: 1002, Relation: 3003, Affinity: 7},
|
||||||
|
{CharaID: 1002, Relation: 3101, Affinity: 7},
|
||||||
|
{CharaID: 1002, Relation: 3205, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 7000, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 7001, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 7002, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 7013, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 7015, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8017, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8018, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8019, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8020, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8021, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8022, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8023, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8024, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8025, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8026, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8027, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8028, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8029, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8030, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8031, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8032, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8444, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8480, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8512, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8537, Affinity: 1},
|
||||||
|
{CharaID: 1002, Relation: 8641, Affinity: 1},
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(want, got); diff != "" {
|
||||||
|
t.Errorf("wrong affinity details (+got/-want):\n%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUmas(t *testing.T) {
|
func TestUmas(t *testing.T) {
|
||||||
db := testdb(t.Context(), "file:TestUmas?mode=memory&cache=shared", characterSQL)
|
db := testdb(t.Context(), "file:TestUmas?mode=memory&cache=shared", characterSQL)
|
||||||
got, err := mdb.Umas(t.Context(), db)
|
got, err := mdb.Umas(t.Context(), db)
|
||||||
|
|||||||
7
mdb/sql/affinity-detail.sql
Normal file
7
mdb/sql/affinity-detail.sql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
SELECT
|
||||||
|
m.chara_id,
|
||||||
|
m.relation_type,
|
||||||
|
r.relation_point
|
||||||
|
FROM succession_relation_member m
|
||||||
|
JOIN succession_relation r ON m.relation_type = r.relation_type
|
||||||
|
ORDER BY m.chara_id, m.relation_type
|
||||||
Reference in New Issue
Block a user