【实战与杂谈】如何复活一个开源网站-游戏王卡片生成器

news2024/11/18 21:43:48

1. 杂谈 

作为一名十多年游戏王玩家,学生时代玩的是PSP和PS2上的游戏,到毕业后使用YGOPRO同步新卡片进行联网对战,再到现在约到线下进行实体卡片游戏。有些卡片价格太贵,因此我们对于这些卡在未购买之前都会自己打印出来暂时游玩。这里不得不提国内的制卡小工具游戏王卡片生成器。

 比较遗憾的是该网站即将下线。

值得庆幸的是作者对网站的更新一直以https://github.com/kooriookami/tools-vue的形式进行保存,本篇博文也是记录博主如何一步一步实现在本地运行起开源项目的经过。 

2. 分析

一般拿到一个开源项目我们可以通过ReadMe了解到他很多相关内容,通过ReadMe可以知道该项目是一个vue开发的前后端分离项目。跟着指引步骤运行项目,非常顺利运行了项目,在本地运行会发现以下问题

3. 解决

这里要介绍杂谈中提到的ygopro,他是一款开源的由国人Fluorohydride(圆神)自制的游戏王决斗系统。在国内我们一般使用萌卡所维护的版本,因此后续的讨论我们都会以萌卡的github项目进行分析。

3.1 获取数据

3.1.1 卡片明细数据

在查看萌卡的项目中的我重点关注标题为YGO的仓库,其中ygopro-database这个仓库,引起我的注意。通过查看他的ReadMe我们可以知道这个项目就是用来管理我们的卡片信息内容。

Some databases of ygopro.

They are for now just for test.

切换到dump分支可以看到通过仓库提供了databases对应数据SQL脚本,这里省下了我很多时间去寻找如何提取数据库文件的卡片数据明细。

这里说一下我在github学习开源项目的另外一个方式就是查看issue,一般在项目上遇到问题都可以在issue进行提问,我在issue中发现这样的提问请问下数据库cdb文件是从哪里获取的,在里面我知道ygo的数据库文件可以通过DataEditorX来提取数据的明细。

3.1.2  卡片插画数据

通过查看源码还有网站公告中我们可以知道ygoprodeck这个网站,他提供了图片API可以进行查看下载。

3.2 功能复现

3.2.1 自建API

通过chrome的开发工具,我们可以知道对应操作下会触发什么样的API请求,那剩下就是分析请求的返回内容与我们手头上的内容进行关联。得益于2.1.1获取到的SQL脚本,我们知道了我们数据收属性结构。

卡片明细表

记录了卡片各内基础信息

CREATE TABLE datas
(
    id integer primary key,
    ot integer,
    alias integer,
    setcode integer,
    type integer,
    atk integer,
    def integer,
    level integer,
    race integer,
    attribute integer,
    category integer
);

卡片描述表

记录卡片的效果信息

CREATE TABLE texts(
    id integer primary key,
    name text,
    desc text,
    str1 text,
    str2 text,
    str3 text,
    str4 text,
    str5 text,
    str6 text,
    str7 text,
    str8 text,
    str9 text,
    str10 text,
    str11 text,
    str12 text,
    str13 text,
    str14 text,
    str15 text,
    str16 text
);

有了图片还有数据信息,只要我们构建API去读取内容即可,详细可以查看我的api项目。

3.2.2 项目本身修改

  • 修改目标API

在main.js我们可以配置数据获取api根目录

// 接口请求地址配置
if (process.env.NODE_ENV === 'production') {
  // 上线环境
  app.config.globalProperties.baseURL = 'http://127.0.0.1:8080/api';//https://tools.kooriookami.top/api
} else {
  // 本地环境
  app.config.globalProperties.baseURL = 'http://127.0.0.1:8080/api';
}
  • 适配简体中文YGOPRO数据

使用自己提供的API的时候会发现当我们查看的是灵摆类的卡片的时候不能正常展示内容,我尝试分析加载数据。我们能发现在网站中加载的灵摆数据json中他们的卡片描述有【Pendulum Effect】、【Monster Effect】

{
    "data": {
        "name": "终焉龙 混沌帝",
        "atk": 3000,
        "def": 2500,
        "attribute": 32,
        "desc": "←1 【Pendulum Effect】 1→\r\n这个卡名的灵摆效果1回合只能使用1次。\r\n①:支付1000基本分,以除外的1只自己的龙族怪兽为对象才能发动。这张卡破坏,那只怪兽加入手卡。\r\n【Monster Effect】\r\n这张卡不能通常召唤。「终焉龙 混沌帝」1回合1次在把自己墓地的光属性和暗属性的怪兽各1只除外的场合才能从手卡·额外卡组特殊召唤。\r\n①:1回合1次,把基本分支付一半才能发动。额外怪兽区域以外的自己场上的卡全部送去墓地,选最多有送去墓地的数量的对方场上的卡送去墓地。那之后,给与对方送去对方墓地的数量×300伤害。\r\n②:特殊召唤的表侧表示的这张卡从场上离开的场合回到卡组最下面。",
        "id": 4538826,
        "level": 16842760,
        "race": 8192,
        "type": 50331681
    },
    "message": "success",
    "status": 200
}

再查看源码,源码也是使用【Pendulum Effect】、【Monster Effect】来数据的提取,因此要根据简体中文YGOPRO数据进行定制化修改。

export function parsePendulumScale(data) {
  if (parseType(data) === 'pendulum') {
    let list = data.desc.split('【Pendulum Effect】');
    return parseInt(list[0]?.replace(/[^\d]/g, ''));
  } else {
    return 0;
  }
}

export function parsePendulumDescription(data, lang) {
  if (parseType(data) === 'pendulum') {
    let description = characterToHalf(data.desc).replace(/'''/g, '')
      .replace(/\r/g, '\n').replace(/(\n)\1*/g, '\n');
    const list = description.split(/【Pendulum Effect】|【Monster Effect】|【Flavor Text】|【怪獸敘述】|【怪獸效果】|【怪獸描述】/).filter(item => item && item !== '\n');
    if (lang === 'tc') {
      description = list[2]?.replace(/\d+→|\n/g, '') || '';
    } else {
      description = list[1]?.replace(/\d+→|\n/g, '') || '';
    }
    if (['jp', 'sc'].includes(lang)) {
      // 效果数字全角,卡名数字半角
      description = numberToFull(description).replace(/(「.*?」)|(“.*?”)/g, s => numberToHalf(s));
    }
    return description.trim();
  } else {
    return '';
  }
}

 根据简体中文YGOPRO数据添加分割简体中文内容的字符

{
    "data": {
        "name": "终焉龙 混沌帝",
        "atk": 3000,
        "def": 2500,
        "attribute": 32,
        "desc": "←1 【灵摆】 1→\r\n这个卡名的灵摆效果1回合只能使用1次。\r\n①:支付1000基本分,以除外的1只自己的龙族怪兽为对象才能发动。这张卡破坏,那只怪兽加入手卡。\r\n【怪兽效果】\r\n这张卡不能通常召唤。「终焉龙 混沌帝」1回合1次在把自己墓地的光属性和暗属性的怪兽各1只除外的场合才能从手卡·额外卡组特殊召唤。\r\n①:1回合1次,把基本分支付一半才能发动。额外怪兽区域以外的自己场上的卡全部送去墓地,选最多有送去墓地的数量的对方场上的卡送去墓地。那之后,给与对方送去对方墓地的数量×300伤害。\r\n②:特殊召唤的表侧表示的这张卡从场上离开的场合回到卡组最下面。",
        "id": 4538826,
        "level": 16842760,
        "race": 8192,
        "type": 50331681
    },
    "message": "success",
    "status": 200
}
export function parsePendulumScale(data) {
  if (parseType(data) === 'pendulum') {
    let list = data.desc.split('【灵摆】');//let list = data.desc.split('【Pendulum Effect】');
    return parseInt(list[0]?.replace(/[^\d]/g, ''));
  } else {
    return 0;
  }
}

export function parsePendulumDescription(data, lang) {
  if (parseType(data) === 'pendulum') {
    let description = characterToHalf(data.desc).replace(/'''/g, '')
      .replace(/\r/g, '\n').replace(/(\n)\1*/g, '\n');
    const list = description.split(/【Pendulum Effect】|【Monster Effect】|【灵摆】|【怪兽效果】|【Flavor Text】|【怪獸敘述】|【怪獸效果】|【怪獸描述】/).filter(item => item && item !== '\n');
    if (lang === 'tc') {
      description = list[2]?.replace(/\d+→|\n/g, '') || '';
    } else {
      description = list[1]?.replace(/\d+→|\n/g, '') || '';
    }
    if (['jp', 'sc'].includes(lang)) {
      // 效果数字全角,卡名数字半角
      description = numberToFull(description).replace(/(「.*?」)|(“.*?”)/g, s => numberToHalf(s));
    }
    return description.trim();
  } else {
    return '';
  }
}
  • 能直加载卡片原画

因为运行成本的原因ygoprodeck提供卡片原画API无法进行外链了,我们通过通告知道还是可以通过ygoprodeck提供的api下载图片,通过自选图片上传来加载卡片原画

 通过添加debugger我们定位到\src\render\views\yugioh.js代码中这段代码负责加载图片

export function parseImage(data) {
 debugger;
 return '/';
}

只要我们拥有自己的图片库,通过自己构建api即可,修改如下,关于如何批量去下载图片请自行在网络上进行查询。

export function parseImage(data) {
 return `http://127.0.0.1:8080/images/${data.id}`;
}

4. 效果

5. 感想

这次网站复活是一个很典型的开源项目应用样例,跳过了开源项目的选型(关于开源项目的选型可以阅读我之前的这篇博客记开源系统落地-我是如何在工作中应用ShardingSphere-JDBC),从使用开源项目,遇到问题如何解决,到最终符合自己的使用需求。

参考:ygocore版本&服务器介绍+操作方法+实用链接

https://github.com/mycard/ygopro-database

修改后代码:GitHub - tale2009/tools-vue

对应后端API:GitHub - tale2009/KenhoYUGIOHAPI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128401.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sec5-属性

1 属性 GObject系统提供属性。属性是由实例保存的值,实例是GObject的后代,它们对其他实例开放。可以通过他们的名字访问他们。 例如,GtkWindow具有"title"、“default-width”、"default-height"等属性。字符串"t…

正经科普:DDos高防ip详解

白衬衫容易发黄, 一般洗衣液很难洗掉, 不少人为此感到头疼, 不妨在洗的时候吃点头痛药。 这边我也不多废话,大家直接看图,高防ip原理如下清洗能力 DDoS高防IP采用BGP链路对接全国各地30家运营商,总防御能力超4T。采用电信云堤近源…

智能优化算法:人工兔优化算法-附代码

智能优化算法:人工兔优化算法 摘要:人工兔优化算法( [Artificial rabbits optimization,RSO)是 Liying Wang等 于 2022 年提出的一种新型元启发式优化算法 。 该算法受来源于自然界中兔子的生存策略的启发,具有寻优能力强&#x…

【2.1】服务拆分--案例Demo

服务拆分--案例Demo服务拆分注意事项:导入服务拆分Demo测试结果:总结知识内容来自于黑马程序员视频教学和百度百科。博主仅作笔记整理便于回顾学习。如有侵权请私信我。 服务拆分注意事项: 比如现在有一个需求,是查询订单&#x…

国产GPU芯片突破重围,迎来新发展,中国崛起的力量

最近,在GPU芯片领域我们终于迎来新进展,有望突破欧美企业垄断,实现完全国产化。高端GPU芯片对科技发展有着重要作用,广泛应用于云上服务、高密度高性能计算等领域,然而绝大部分GPU芯片市场都被英伟达、AMD、微软等国外…

骨传导耳挂式耳机排名前十名,最好的骨传导耳机推荐

挂耳式的骨传导耳机在佩戴时更舒适以及更加牢固,日常在多种场景使用都能完全兼顾。但是最好的骨传导耳机有哪些呢?还不知道如何选择骨传导耳机,可以看看这五款骨传导耳机~ 1、南卡Runner Pro4骨传导蓝牙耳机 ¥1498 选择骨传导耳机…

Kubernetes那点事儿——控制器Deployment

K8s应用程序生命周期管理——控制器Deployment一、部署应用程序流程二、Deployment控制器1、应用升级、弹性伸缩、回滚、删除2、滚动升级、回滚机制3、定义Deployment前言说到K8s程序的生命周期管理我们不得不提到k8s的控制器。其中Deployment是最为常用的controllers&#xff…

Liga妙谈 | 如何快速甄别、高效响应用户反馈?

敏捷开发说要「拥抱变化」,在充满不确定的环境中,唯一不变的正是变化。面对源源不断的市场反馈和需求变更,敏捷团队应该如何平衡「高效迭代」与「响应用户」的关系,既快又好地完成研发任务,交付业务价值? …

FFmpeg 滤镜详解

FFmpeg Filter 1. 概念介绍 在多媒体处理中,术语滤镜(filter)指的是修改未编码的原始音视频数据帧的一种软件工具。 2. 基本原理 ● 在编码前,ffmpeg可以对raw(真实/原)音频和视频使用libavfilter库中的滤镜进行处理。(非压缩…

骨感传导蓝牙耳机怎么样、骨感传导蓝牙耳机有什么特点

在正文开始前,先跟大家说明一下,骨感传导其实就是我们常说的骨传导,两者是相同的意思,只是表达的文字不太一样。我们可以理解为骨感传导耳机骨传导耳机,那既然是这样,骨传导耳机又是利用什么原理传播声音的…

CentOS搭建web服务器,并内网穿透实现公网访问

在web项目中,部署的web站点需要被外部访问,则需要一个媒介,通过把资源放在这个媒介中,再通过所暴露的端口指向这个站点,当外部访问这个媒介所对应的端口时,媒介指向站点,完成访问,像这种类似的媒介,常用的有tomcat容器、Apache等,这边使用Apache来建搭建。 Apache2 是一种流行…

一节摹课丨做会动的电子贺卡,当懂浪漫的成年人

你正在阅读摹客全新内容栏目【一节摹课】。 本栏目会通过一些有趣的、实用的、好看的、新潮的实操案例,分享摹客“设计12”产品矩阵 —— 「1个协作平台2款设计工具」的具体操作妙计! 带大家一步一步地解锁摹客协作、摹客RP、摹客DT中的大小功能。 一…

非正式全面解析 NebulaGraph 中 Session 管理

NebulaGraph 论坛最近有些讨论帖,各种姿势来问 NebulaGraph Session 管理相关的事情,我寻思这也不是一个法子,还是来写一篇文章来讲述下 NebulaGraph 中的 Session 管理。由于本文设定为非正式的 Session 讲解,所以本文主要分为理…

智能车|直流电机、编码器与驱动器---编码器

智能车|直流电机、编码器与驱动器---编码器编码器编码器简介编码器的工作原理四倍频采集编码器采集程序实现编码器 编码器简介 编码器是一种将角位移或者直线位移转换成一连串电数字脉冲的一种传感器。 可以通过编码器测量电机转动的位移或者速度信息。 编码器按照工作原理…

FTP多目录和多用户配置(用户隔离/虚拟目录)

FTP多目录和多用户配置(用户隔离/虚拟目录) 假设有四个部门分别是user1、user2、user3、admin。要求四个部门都有各自有独立的访问目录,且admin部门可以访问其他部门的文件但不能对其进行修改。 1、创建ftp文件→再创建LocalUser(…

【图像处理OpenCV(C++版)】——3.1几何变换之仿射变换

前言: 😊😊😊欢迎来到本博客😊😊😊 🌟🌟🌟 本专栏主要结合OpenCV和C来实现一些基本的图像处理算法并详细解释各参数含义,适用于平时学习、工作快…

CSS 颜色

文章目录CSS 颜色关键字 & 十六进制 & RGBopacity 透明度RGBA 颜色CSS3 渐变线性渐变径向渐变CSS 颜色 关键字 & 十六进制 & RGB W3C十六色 opacity 透明度 语法 opacity: 数值;说明 在CSS3中,我们可以使用opacity属性来定义元素的透明度。 o…

excel排序求和:如何统计前几名数据合计 下篇

上次咱们说到一个公式SUM(LARGE(B:B,ROW(INDIRECT("1:"&H2)))),其中的ROW(INDIRECT("1:"&H2))这部分如果写成ROW(1:H2)就会报错: 原因也告诉大家了,就是ROW函数的参数只能使用单元格或单元格区域。 因此解决的办…

Java IO流 - 字节流的使用详细介绍

文章目录IO流的基本介绍字节流的使用文件字节输入流创建字节输入流每次读取一个字节每次读取一个数组一次读取全部字节文件字节输出流创建字节输出流写入文件输出流文件拷贝练习IO流的基本介绍 IO流的概述: I 表示intput,是数据从硬盘文件读入到内存的过程&#xf…

频谱分析仪关键性能指标

频谱分析仪关键性能指标 频谱分析仪作为分析仪表,其基本性能要求包含: 1. 频率方面指标: 测量频率范围:反映频谱仪测量信号范围能力; 频率分辨率:反映频谱仪分辨两个频率间隔信号的能力。 2. 幅方面度指标&#x…