Commit 50f97279 authored by nanahira's avatar nanahira

get rid of express.Response

parent 68a40801
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
"sourceRoot": "src",
"compilerOptions": {
"plugins": ["@nestjs/swagger"]
}
}
This diff is collapsed.
export const CardInfo = {
cn: {
'1010': '',
'1011': '',
'1012': '',
'1013': '',
'1014': '',
'1015': '',
'1016': '',
'1020': '战士',
'1021': '魔法师',
'1022': '天使',
'1023': '恶魔',
'1024': '不死',
'1025': '机械',
'1026': '',
'1027': '',
'1028': '岩石',
'1029': '鸟兽',
'1030': '植物',
'1031': '昆虫',
'1032': '',
'1033': '',
'1034': '',
'1035': '兽战士',
'1036': '恐龙',
'1037': '',
'1038': '海龙',
'1039': '爬虫',
'1040': '念动力',
'1041': '幻神兽',
'1042': '创造神',
'1043': '幻龙',
'1044': '电子界',
'1050': '怪兽',
'1051': '魔法',
'1052': '陷阱',
'1053': '???',
'1054': '通常',
'1055': '效果',
'1056': '融合',
'1057': '仪式',
'1058': '陷阱怪兽',
'1059': '灵魂',
'1060': '同盟',
'1061': '二重',
'1062': '调整',
'1063': '同调',
'1064': '衍生物',
'1065': '???',
'1066': '速攻',
'1067': '永续',
'1068': '装备',
'1069': '场地',
'1070': '反击',
'1071': '反转',
'1072': '卡通',
'1073': '超量',
'1074': '灵摆',
},
en: {
'1010': 'EARTH',
'1011': 'WATER',
'1012': 'FIRE',
'1013': 'WIND',
'1014': 'LIGHT',
'1015': 'DARK',
'1016': 'DIVINE',
'1020': 'Warrior',
'1021': 'Spellcaster',
'1022': 'Fairy',
'1023': 'Fiend',
'1024': 'Zombie',
'1025': 'Machine',
'1026': 'Aqua',
'1027': 'Pyro',
'1028': 'Rock',
'1029': 'Winged Beast',
'1030': 'Plant',
'1031': 'Insect',
'1032': 'Thunder',
'1033': 'Dragon',
'1034': 'Beast',
'1035': 'Beast-Warrior',
'1036': 'Dinosaur',
'1037': 'Fish',
'1038': 'Sea Serpent',
'1039': 'Reptile',
'1040': 'Psychic',
'1041': 'Divine-Beast',
'1042': 'Creator God',
'1043': 'Wyrm',
'1044': 'Cyberse',
'1050': 'Monster',
'1051': 'Spell',
'1052': 'Trap',
'1053': '???',
'1054': 'Normal',
'1055': 'Effect',
'1056': 'Fusion',
'1057': 'Ritual',
'1058': 'Trap Monster',
'1059': 'Spirit',
'1060': 'Union',
'1061': 'Gemini',
'1062': 'Tuner',
'1063': 'Synchro',
'1064': 'Token',
'1065': '???',
'1066': 'Quick-Play',
'1067': 'Continuous',
'1068': 'Equip',
'1069': 'Field',
'1070': 'Counter',
'1071': 'Flip',
'1072': 'Toon',
'1073': 'Xyz',
'1074': 'Pendulum',
},
};
export function getStringValueByMysticalNumber(
lang: string,
offset: number,
num: number,
) {
for (let i = 0; i < 32; i++) {
if (num & (1 << i)) {
const index = offset + i;
const key = index.toString();
return CardInfo[lang][key];
}
}
return '';
}
export class EloUtility {
static getExpScore(
expA: number,
expB: number,
scoreA: number,
scoreB: number,
) {
let rExpA = expA,
rExpB = expB;
if (scoreA === scoreB) {
rExpA += 0.5;
rExpB += 0.5;
} else if (scoreA > scoreB) {
rExpA += 1;
if (expA > expB) rExpB += 0.5;
} else if (scoreA < scoreB) {
rExpB += 1;
if (expA < expB) rExpA += 0.5;
}
return { expA: rExpA, expB: rExpB };
}
static getEloScore(rA: number, rB: number, sA: number, sB: number) {
//17.07.18 增加规则,平局不加分.
if (sA === sB) {
return { ptA: rA, ptB: rB };
}
const k = 24;
const eA = 1 / (1 + Math.pow(10, (rB - rA) / 400));
const eB = 1 / (1 + Math.pow(10, (rA - rB) / 400));
let diffA = k * (sA - eA);
// 如果算出的变动分数小于8或者大于16就按8和16计
if (diffA > 0 && diffA > 16) {
//console.log("diffA 加分大于16 按16分结算", diffA);
diffA = 16;
}
if (diffA > 0 && diffA < 8) {
//console.log("diffA 加分小于8 按8分结算", diffA);
diffA = 8;
}
if (diffA < 0 && diffA > -8) {
//console.log("diffA 扣分小于8 按8分结算算", diffA);
diffA = -8;
}
if (diffA < 0 && diffA < -15) {
//console.log("diffA 扣分大于16 按16分结算", diffA);
diffA = -15;
}
const rrA = rA + diffA;
let diffB = k * (sB - eB);
// 如果算出的变动分数小于8或者大于16就按8和16计
if (diffB > 0 && diffB > 16) {
//console.log("diffB 加分大于16 按16分结算", diffB);
diffB = 16;
}
if (diffB > 0 && diffB < 8) {
//console.log("diffB 加分小于8 按8分结算", diffB);
diffB = 8;
}
if (diffB < 0 && diffB > -8) {
//console.log("diffB 扣分小于8 按8分结算算", diffB);
diffB = -8;
}
if (diffB < 0 && diffB < -15) {
//console.log("diffB 扣分大于16 按16分结算", diffB);
diffB = -15;
}
const rrB = rB + diffB;
//console.log(diffA, diffB);
// // 加分高于16
// if( (rrB - rB) > 16 ) {
// rrB = rB + 16;
// }
// // 扣分低于8
// if( (rB - rrB) < 8 ) {
// rrB = rB - 8;
// }
return { ptA: rrA, ptB: rrB };
}
}
This diff is collapsed.
......@@ -46,6 +46,11 @@ import { DeckSeason } from './entities/mycard/DeckSeason';
import { DeckWeek } from './entities/mycard/DeckWeek';
import { UserInfo } from './entities/mycard/UserInfo';
import { AppLogger } from './app.logger';
import { HttpResponseService } from './http-response/http-response.service';
import { EloService } from './elo/elo.service';
import { CardInfoService } from './card-info/card-info.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
const ygoproEntities = [YGOProDatabaseDatas, YGOProDatabaseTexts];
const mycardEntities = [
......@@ -93,6 +98,10 @@ const mycardEntities = [
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'upload'),
serveRoot: '/api/download',
}),
TypeOrmModule.forRoot({
synchronize: false,
type: 'sqlite',
......@@ -120,6 +129,12 @@ const mycardEntities = [
}),
],
controllers: [AppController],
providers: [AppService, AppLogger],
providers: [
AppService,
AppLogger,
HttpResponseService,
EloService,
CardInfoService,
],
})
export class AppModule {}
......@@ -15,7 +15,6 @@ import Filter from 'bad-words-chinese';
import { ChineseDirtyWords } from './dirtyWordsChinese';
import { YGOProDatabaseDatas } from './entities/ygodb/YGOProDatabaseDatas';
import { YGOProDatabaseTexts } from './entities/ygodb/YGOProDatabaseTexts';
import { getStringValueByMysticalNumber } from './CardInfo';
import moment from 'moment';
import { BattleHistory } from './entities/mycard/BattleHistory';
import _ from 'underscore';
......@@ -24,7 +23,6 @@ import { AppLogger } from './app.logger';
import axios from 'axios';
import { config } from './config';
import qs from 'qs';
import { EloUtility } from './EloUtility';
import { Votes } from './entities/mycard/Votes';
import { VoteResult } from './entities/mycard/VoteResult';
import { promises as fs } from 'fs';
......@@ -32,10 +30,11 @@ import { scheduleJob } from 'node-schedule';
import { DeckInfo } from './entities/mycard/DeckInfo';
import { DeckInfoHistory } from './entities/mycard/DeckInfoHistory';
import { DeckDemo } from './entities/mycard/DeckDemo';
import { Deck } from './entities/mycard/Deck';
import { Ads } from './entities/mycard/Ads';
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
import { DeckInfoOrHistory } from './entities/mycard/DeckInfoOrHistory';
import { EloService } from './elo/elo.service';
import { CardInfoService } from './card-info/card-info.service';
const attrOffset = 1010;
const raceOffset = 1020;
......@@ -99,7 +98,7 @@ interface VoteOption {
percentage: number;
}
interface DeckInfoCard {
export interface DeckInfoCard {
id: number;
num: number;
name?: string;
......@@ -117,6 +116,8 @@ export class AppService {
@InjectConnection('mycard')
private mcdb: Connection,
private log: AppLogger,
private eloService: EloService,
private cardInfoService: CardInfoService,
) {
this.log.setContext('ygopro-arena-revive');
this.chineseDirtyFilter = new Filter({
......@@ -259,17 +260,17 @@ export class AppService {
result.category = cardDatas.category;
result.type = getStringValueByMysticalNumber(
result.type = this.cardInfoService.getStringValueByMysticalNumber(
lang,
typeOffset,
cardDatas.type,
);
result.race = getStringValueByMysticalNumber(
result.race = this.cardInfoService.getStringValueByMysticalNumber(
lang,
raceOffset,
cardDatas.race,
);
result.attribute = getStringValueByMysticalNumber(
result.attribute = this.cardInfoService.getStringValueByMysticalNumber(
lang,
attrOffset,
cardDatas.attribute,
......@@ -630,8 +631,8 @@ export class AppService {
}
}
const ptResult = EloUtility.getEloScore(userA.pt, userB.pt, sa, sb);
const expResult = EloUtility.getExpScore(
const ptResult = this.eloService.getEloScore(userA.pt, userB.pt, sa, sb);
const expResult = this.eloService.getExpScore(
userA.exp,
userB.exp,
userscoreA,
......@@ -849,7 +850,7 @@ export class AppService {
}
});
} else {
const expResult = EloUtility.getExpScore(
const expResult = this.eloService.getExpScore(
userA.exp,
userB.exp,
userscoreA,
......@@ -1239,7 +1240,11 @@ export class AppService {
return;
}
item.name = card.texts.name;
item.type = getStringValueByMysticalNumber(lang, typeOffset, card.type);
item.type = this.cardInfoService.getStringValueByMysticalNumber(
lang,
typeOffset,
card.type,
);
}
private async fillCardInfoBatch(arr: DeckInfoCard[]) {
......
import { ApiProperty } from '@nestjs/swagger';
export class CodeResponseDto {
@ApiProperty({ description: '状态码' })
code: number;
@ApiProperty({ description: '是否成功' })
success: boolean;
constructor(code: number) {
this.success = code < 400;
this.code = code;
}
}
import { ApiProperty } from '@nestjs/swagger';
export class FileUploadDto {
@ApiProperty({ type: 'string', format: 'binary' })
file: any;
}
import { Column, Entity, PrimaryColumn } from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
@Entity('user_info', { schema: 'public' })
export class UserInfo {
@ApiProperty({ description: '用户名' })
@PrimaryColumn('character varying', { name: 'username', length: 100 })
username: string;
@ApiProperty({ description: 'EXP 数值' })
@Column('double precision', {
name: 'exp',
precision: 53,
......@@ -12,6 +15,7 @@ export class UserInfo {
})
exp: number;
@ApiProperty({ description: 'DP 数值' })
@Column('double precision', {
name: 'pt',
precision: 53,
......@@ -19,30 +23,39 @@ export class UserInfo {
})
pt: number;
@ApiProperty({ description: '娱乐匹配胜利数' })
@Column('integer', { name: 'entertain_win', default: 0 })
entertain_win: number;
@ApiProperty({ description: '娱乐匹配失败数' })
@Column('integer', { name: 'entertain_lose', default: 0 })
entertain_lose: number;
@ApiProperty({ description: '娱乐匹配平局数' })
@Column('integer', { name: 'entertain_draw', default: 0 })
entertain_draw: number;
@ApiProperty({ description: '娱乐匹配总数' })
@Column('integer', { name: 'entertain_all', default: 0 })
entertain_all: number;
@ApiProperty({ description: '竞技匹配胜利数' })
@Column('integer', { name: 'athletic_win', default: 0 })
athletic_win: number;
@ApiProperty({ description: '竞技匹配失败数' })
@Column('integer', { name: 'athletic_lose', default: 0 })
athletic_lose: number;
@ApiProperty({ description: '竞技匹配平局数' })
@Column('integer', { name: 'athletic_draw', default: 0 })
athletic_draw: number;
@ApiProperty({ description: '竞技匹配总数' })
@Column('integer', { name: 'athletic_all', default: 0 })
athletic_all: number;
@ApiProperty({ description: '玩家 ID' })
@Column('integer', { name: 'id', nullable: true })
id: number;
}
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import bodyParser from 'body-parser';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
const documentConfig = new DocumentBuilder()
.setTitle('ygopro-arena-api')
.setDescription('YGOPro 决斗数据库后台')
.setVersion('1.0')
.addTag('arena')
.build();
const document = SwaggerModule.createDocument(app, documentConfig);
SwaggerModule.setup('docs', app, document);
app.use(bodyParser.json({ limit: '50mb' }));
app.use(
bodyParser.urlencoded({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment