This commit is contained in:
Yutousama 2022-08-22 21:39:06 +08:00
parent 6857a1d5ea
commit 0ee1be5f04
8 changed files with 418 additions and 51 deletions

View File

@ -0,0 +1,26 @@
package com.yutou.qqbot.Controllers;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.utlis.CalendarTools;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class CalendarController {
@ResponseBody
@RequestMapping("/calendar/all.do")
public JSONObject getCalendar(){
JSONObject json = new JSONObject();
JSONObject holiday= CalendarTools.getHoliday();
json.put("data",holiday);
return json;
}
@ResponseBody
@RequestMapping("/calendar/set.do")
public JSONObject setCalendar(String startDate,String interval){
JSONObject json = new JSONObject();
return json;
}
}

View File

@ -294,4 +294,10 @@ public class BiliBiliUtils {
} }
return jsonObject; return jsonObject;
} }
public static void main(String[] args) {
String url="https://xy218x85x123x8xy.mcdn.bilivideo.cn:4483/upgcxcode/12/12/17281212/17281212-16-80.flv?e=ig8euxZM2rNcNbNBhbdVhwdlhbUghwdVhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1660538573&gen=playurlv2&os=mcdn&oi=2936701972&trid=00006f9623cac1514d8ea18fba3a15a756cau&mid=96300&platform=pc&upsig=25ddd1da610960e8e1d2e80dc97c2361&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform&mcdnid=11000101&bvc=vod&nettype=0&orderid=0,2&agrr=1&bw=253116&logo=A0000400&requestFrom=BILIBILI_HELPER_2.5.8";
File file=BiliBiliUtils.download(url,"16.mp4",false);
System.out.println("file.getAbsolutePath() = " + file.getAbsolutePath());
}
} }

View File

@ -30,6 +30,20 @@ public class AndroidDevice {
public double getHeight() { public double getHeight() {
return end.getY() - start.getY(); return end.getY() - start.getY();
} }
public void setEnabledRandom(boolean enabled) {
if(enabled){
start.setEnableRandomY(true);
start.setEnableRandomX(true);
end.setEnableRandomX(true);
end.setEnableRandomY(true);
}else{
start.setEnableRandomX(false);
start.setEnableRandomY(false);
end.setEnableRandomY(false);
end.setEnableRandomX(false);
}
}
} }
} }

View File

@ -23,6 +23,13 @@ public class Vector2D {
} }
return x; return x;
} }
public double getNotRandomY() {
return y;
}
public double getNotRandomX() {
return x;
}
public double getY() { public double getY() {
if(isEnableRandomY()){ if(isEnableRandomY()){

View File

@ -0,0 +1,61 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSONObject;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.Set;
public class CalendarTools {
private static final String REDIS_TAG="Calendar";
public static JSONObject getHoliday() {
int month = Calendar.getInstance(DateFormat.getDateInstance().getTimeZone(), Locale.CHINA).get(Calendar.MONTH) + 1;
int year = Calendar.getInstance(DateFormat.getDateInstance().getTimeZone(), Locale.CHINA).get(Calendar.YEAR);
return getHoliday(year + "", null);
}
public static JSONObject getHoliday(String year, String month) {
String get = HttpTools.get(String.format("https://timor.tech/api/holiday/year/%s", year));
JSONObject json = JSONObject.parseObject(get);
JSONObject date = new JSONObject();
JSONObject dateHoliday = new JSONObject();
JSONObject holiday = json.getJSONObject("holiday");
for (String key : holiday.keySet()) {
JSONObject _tmp = holiday.getJSONObject(key);
date.put(year + "-" + key, _tmp.getString("name"));
dateHoliday.put(year + "-" + key, _tmp.getBooleanValue("holiday"));
}
JSONObject tmp = new JSONObject();
tmp.put("date", date);
tmp.put("holiday", dateHoliday);
return tmp;
}
public static boolean isHoliday() {
Calendar calendar=Calendar.getInstance(DateFormat.getDateInstance().getTimeZone(), Locale.CHINA);
Calendar calendar2=Calendar.getInstance(DateFormat.getDateInstance().getTimeZone(), Locale.CHINA);
Set<String> list = RedisTools.list_get(REDIS_TAG);
for (String s : list) {
}
return false;
}
public static void main(String[] args) {
Calendar calendar=Calendar.getInstance(DateFormat.getDateInstance().getTimeZone(), Locale.CHINA);
Calendar calendar2=Calendar.getInstance(DateFormat.getDateInstance().getTimeZone(), Locale.CHINA);
int start = 6;
int in = 14;
calendar.set(Calendar.MONTH,7);
calendar.set(Calendar.DATE,start);
calendar2.set(Calendar.DATE,13);
long t2=calendar2.getTime().getTime();
long t1=calendar.getTime().getTime();
long l = calendar2.getTime().getTime() - calendar.getTime().getTime();
long interval=l/1000/60/60/24;
System.out.println(interval);
System.out.println("t1 = " + t1);
System.out.println("t2 = " + t2);
System.out.println("interval = " + interval%in);
}
}

View File

@ -1,14 +1,19 @@
package com.yutou.qqbot.utlis; package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.data.jianr.AndroidDevice; import com.yutou.qqbot.data.jianr.AndroidDevice;
import com.yutou.qqbot.data.jianr.JianRScriptData; import com.yutou.qqbot.data.jianr.JianRScriptData;
import com.yutou.qqbot.data.jianr.JianRScriptV2Data; import com.yutou.qqbot.data.jianr.JianRScriptV2Data;
import com.yutou.qqbot.data.jianr.Vector2D; import com.yutou.qqbot.data.jianr.Vector2D;
import com.yutou.qqbot.interfaces.ObjectInterface;
import lombok.SneakyThrows;
import java.util.ArrayList; import javax.imageio.ImageIO;
import java.util.List; import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random; import java.util.Random;
import java.util.TreeMap;
public class JianRTaskManager { public class JianRTaskManager {
public static final String Redis_Script = "jianrScript_Script"; public static final String Redis_Script = "jianrScript_Script";
@ -49,10 +54,10 @@ public class JianRTaskManager {
} }
public void start() { public void start() {
if (running||runStatus) { if (running || runStatus) {
return; return;
} }
runStatus=true; runStatus = true;
running = true; running = true;
new Thread(new Runnable() { new Thread(new Runnable() {
@ -68,10 +73,16 @@ public class JianRTaskManager {
} }
log(script.getTitle()); log(script.getTitle());
JianRTaskManager.this.run(device, modelId, script); JianRTaskManager.this.run(device, modelId, script);
try { /* try {
Thread.sleep((long) getRandom(0, script.getRandomNextWaitTime() * 1000, script.getNextWaitTime() * 1000)); Thread.sleep((long) getRandom(0, script.getRandomNextWaitTime() * 1000, script.getNextWaitTime() * 1000));
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
}*/
while (true){
if(waitGame(device,modelId,script)){
System.out.println("next");
break;
}
} }
} }
runIndex++; runIndex++;
@ -82,43 +93,87 @@ public class JianRTaskManager {
} }
} }
runStatus=false; runStatus = false;
log("终止任务"); log("终止任务");
} }
}).start(); }).start();
} }
Vector2D nowVector2D = null;
private void run(AndroidDevice device, int modelId, JianRScriptV2Data.Script script) { private void run(AndroidDevice device, int modelId, JianRScriptV2Data.Script script) {
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId); AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
Vector2D vector2D = null;
switch (script.getActivity()) { switch (script.getActivity()) {
case JianRScriptV2Data.ScriptModel.MAP: case JianRScriptV2Data.ScriptModel.MAP:
vector2D = getMapCoords(device, gameDisplay); nowVector2D = getMapCoords(device, gameDisplay);
break; break;
case JianRScriptV2Data.ScriptModel.attack: case JianRScriptV2Data.ScriptModel.attack:
vector2D = getAttackCoords(device, gameDisplay); nowVector2D = getAttackCoords(device, gameDisplay);
break; break;
case JianRScriptV2Data.ScriptModel.dialog_go: case JianRScriptV2Data.ScriptModel.dialog_go:
vector2D = getDialogCoords(device, gameDisplay, false); nowVector2D = getDialogCoords(device, gameDisplay, false);
break; break;
case JianRScriptV2Data.ScriptModel.dialog_back: case JianRScriptV2Data.ScriptModel.dialog_back:
vector2D = getDialogCoords(device, gameDisplay, true); nowVector2D = getDialogCoords(device, gameDisplay, true);
break; break;
case JianRScriptV2Data.ScriptModel.dialog_assets: case JianRScriptV2Data.ScriptModel.dialog_assets:
vector2D = getDialogAssetsCoords(device, gameDisplay); nowVector2D = getDialogAssetsCoords(device, gameDisplay);
break; break;
case JianRScriptV2Data.ScriptModel.none: case JianRScriptV2Data.ScriptModel.none:
vector2D=getNoneCoords(device, gameDisplay); nowVector2D = getNoneCoords(device, gameDisplay);
break; break;
default: default:
if (script.getActivity().startsWith(JianRScriptV2Data.ScriptModel.formationType)) { if (script.getActivity().startsWith(JianRScriptV2Data.ScriptModel.formationType)) {
vector2D = getNextFormationCoords(device, gameDisplay, Integer.parseInt(script.getActivity().split("#")[1])); nowVector2D = getNextFormationCoords(device, gameDisplay, Integer.parseInt(script.getActivity().split("#")[1]));
} }
} }
if (vector2D != null) { if (nowVector2D != null) {
adb(device, vector2D); adb(device, nowVector2D);
} }
} }
private boolean isAttack=false;
private boolean isFormation=false;
private boolean waitGame(AndroidDevice device, int modelId,JianRScriptV2Data.Script script) {
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
String ocr;
switch (script.getActivity()) {
case JianRScriptV2Data.ScriptModel.MAP:
ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
System.out.println("ocr = " + ocr);
if(ocr.trim().contains("开始出征")){
return true;
}
break;
case JianRScriptV2Data.ScriptModel.attack:
ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
System.out.println("ocr = " + ocr);
if(ocr.trim().contains("开始战斗")){
isAttack=true;
}
if(isAttack){
run(device, modelId, script);
isFormation= true;
}
if(isFormation){
ocr=screen(gameDisplay,getDialogCoords(device,gameDisplay,true));
String tmp=screen(gameDisplay,getContinueCoords(device,gameDisplay));
if(ocr.contains("放弃")||tmp.contains("继续")){
}
}
break;
case JianRScriptV2Data.ScriptModel.dialog_go:
break;
case JianRScriptV2Data.ScriptModel.dialog_back:
break;
case JianRScriptV2Data.ScriptModel.dialog_assets:
break;
case JianRScriptV2Data.ScriptModel.none:
break;
default:
}
return false;
}
public void stop() { public void stop() {
task = null; task = null;
@ -194,6 +249,13 @@ public class JianRTaskManager {
return v2d; return v2d;
} }
private Vector2D getContinueCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.8725 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.9 + gameDisplay.getStart().getY());
return v2d;
}
/** /**
* 获取地图点击坐标 * 获取地图点击坐标
* *
@ -225,6 +287,13 @@ public class JianRTaskManager {
return v2d; return v2d;
} }
public Vector2D getBottomLeft(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getEnd().getY());
return v2d;
}
/** /**
* 获取出击坐标 * 获取出击坐标
* *
@ -253,48 +322,110 @@ public class JianRTaskManager {
v2d.setY(gameDisplay.getHeight() * 0.5433 + gameDisplay.getStart().getY()); v2d.setY(gameDisplay.getHeight() * 0.5433 + gameDisplay.getStart().getY());
return v2d; return v2d;
} }
private Vector2D getNoneCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay){
private Vector2D getNoneCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D(); Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.1 + gameDisplay.getStart().getX()); v2d.setX(gameDisplay.getWidth() * 0.1 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.1 + gameDisplay.getStart().getY()); v2d.setY(gameDisplay.getHeight() * 0.1 + gameDisplay.getStart().getY());
return v2d; return v2d;
} }
@SneakyThrows
public static void main(String[] args) { public static void main(String[] args) {
AndroidDevice device = new AndroidDevice(); JSONObject json = new JSONObject();
AndroidDevice.DeviceDisplay deviceDisplay = new AndroidDevice.DeviceDisplay(); String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
AndroidDevice.GameDisplay gameDisplay = new AndroidDevice.GameDisplay(); String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
deviceDisplay.setHeight(1800); if (data == null || deviceJsonString == null) {
deviceDisplay.setWidth(2800); json.put("code", -1);
Vector2D start = new Vector2D(); json.put("msg", "没有找到该方案或设备错误,请配置");
Vector2D end = new Vector2D(); } else {
start.setX(2000); JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
start.setY(57); AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
end.setX(2800); JianRTaskManager manager = JianRTaskManager.getInstance();
end.setY(581); if (manager.isRunning()) {
gameDisplay.setStart(start); manager.stop();
gameDisplay.setEnd(end); }
List<AndroidDevice.GameDisplay> displays = new ArrayList<>(); for (int i = 0; i < androidDevice.getDeviceDisplay().size(); i++) {
displays.add(gameDisplay); if (androidDevice.getDeviceDisplay().get(i).getTitle().equals("全屏模式")) {
device.setDeviceDisplay(displays); manager.setModelId(i);
device.setAndroidDevice(deviceDisplay); break;
device.setDeviceId("192.168.31.142:6666"); }
device.setTitle("SAMSUNG-TAB-S7+"); }
manager.setTask(script, androidDevice);
JianRTaskManager manager = new JianRTaskManager();
Vector2D mapCoords;
// mapCoords = manager.getMapCoords(device,device.getGameDisplay().get(0));
// mapCoords = manager.getAttackCoords(device,device.getGameDisplay().get(0));
// mapCoords = manager.getNextFormationCoords(device,device.getGameDisplay().get(0), 0);
mapCoords = manager.getDialogCoords(device, device.getDeviceDisplay().get(0), true);
// adb(device, mapCoords);
System.out.println("device = " + device);
String jsonString = "{\"name\":\"1-1Test\",\"script\":[{\"name\":\"点击地图\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"出击\",\"activity\":\"attack\",\"nextWaitTime\":12,\"randomNextWaitTime\":2},{\"name\":\"战斗\",\"activity\":\"attack\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"选择单纵\",\"activity\":\"formationType#0\",\"nextWaitTime\":20,\"randomNextWaitTime\":5},{\"name\":\"结算1\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"结算2\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"获取舰娘\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"前进\",\"activity\":\"dialog_go\",\"nextWaitTime\":12,\"randomNextWaitTime\":3},{\"name\":\"战斗\",\"activity\":\"attack\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"选择梯形\",\"activity\":\"formationType#3\",\"nextWaitTime\":20,\"randomNextWaitTime\":5},{\"name\":\"结算1\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"结算2\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"获取舰娘\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3}]}";
JianRScriptV2Data script = JSON.parseObject(jsonString, JianRScriptV2Data.class);
manager.setTask(script, device);
manager.setModelId(0);
manager.start(); manager.start();
} }
}
public File cut(Vector2D v2d) {
try {
System.out.println("v2d = " + v2d);
int x = (int) v2d.getNotRandomX() - 150;
int y = (int) v2d.getNotRandomY() - 50;
if (y + 150 > device.getAndroidDevice().getHeight()) {
y -= 100;
}
if (y < 0) {
y = 0;
}
if (x + 450 > device.getAndroidDevice().getWidth()) {
x -= 300;
}
if (x < 0) {
x = 0;
}
System.out.println("x = " + x);
System.out.println("y = " + y);
BufferedImage bufImage = ImageIO.read(new File("1.png"));
BufferedImage bufferedImage = bufImage.getSubimage(x, y, 400, 100);
File imgCutFile = new File("tmp.png");
ImageIO.write(bufferedImage, "PNG", imgCutFile);
return imgCutFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static String ocr(File file) {
String exec = "\"C:\\Program Files\\Tesseract-OCR\\tesseract.exe\" " + file.getAbsolutePath() + " - -l chi_sim --psm 6";
return AppTools.exec(exec, null, false, true).replace("\r", "").replace("\n", "");
}
private String screen(AndroidDevice.GameDisplay gameDisplay, Vector2D v2d) {
AppTools.exec("adb exec-out screencap -p > 1.png", null, false, false);
gameDisplay.setEnabledRandom(false);
File file = cut(v2d);
return ocr(file);
}
public void test() {
String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
this.device = androidDevice;
this.task = script;
this.modelId = 1;
System.out.println("download image");
AppTools.exec("adb exec-out screencap -p > 1.png", new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
AndroidDevice dev = device;
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
gameDisplay.setEnabledRandom(false);
Vector2D v2d;
v2d = getBottomLeft(device, gameDisplay);
v2d = getNextFormationCoords(device, gameDisplay, 4);
v2d = getAttackCoords(device, gameDisplay);
v2d = getDialogCoords(device, device.getDeviceDisplay().get(modelId), true);
v2d = getContinueCoords(device, gameDisplay);
File file = cut(v2d);
String ocr = ocr(file);
System.out.println(ocr.trim());
}
}, false, true);
}
private void adb(AndroidDevice device, Vector2D v2d) { private void adb(AndroidDevice device, Vector2D v2d) {
String exec = String.format("adb -s %s shell input tap %f %f", String exec = String.format("adb -s %s shell input tap %f %f",

View File

@ -204,9 +204,9 @@ public class RedisTools {
public static boolean setHashMap(String hashKey, String key, String value) { public static boolean setHashMap(String hashKey, String key, String value) {
Jedis jedis = getRedis(); Jedis jedis = getRedis();
long l = jedis.hsetnx(hashKey, key, value); long l = jedis.hset(hashKey, key, value);
jedis.close(); jedis.close();
return l > 0; return l == 0;
} }
public static boolean removeHashMap(String hashKey, String key) { public static boolean removeHashMap(String hashKey, String key) {

122
web/calendar.html Normal file
View File

@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>BiliBili下载器</title>
<link rel="stylesheet" href="layui/css/layui.css" media="all">
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
</head>
<body>
<div class="myDiy">
<blockquote class="layui-elem-quote">日历管理
</blockquote>
<br/><br/><br/>
<div class="layui-bg-gray layui-row layui-col-space15" id="card" style="padding: 30px;">
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label">日历</label>
<div class="layui-input-block">
<div id="calendar"/>
</div>
</div>
<br/>
<br/>
<br/>
<div class="layui-form-item">
<label class="layui-form-label">间隔</label>
<div class="layui-input-block">
<select id="interval" lay-verify="required">
<option value=""></option>
<option value="0">相隔X天</option>
<option value="1">每周X</option>
<option value="2">每月X号</option>
</select>
</div>
</div>
<blockquote class="layui-elem-quote"><span id="dateText">日期选择</span>
</blockquote>
<div class="layui-form-item">
<label class="layui-form-label">间隔日期</label>
<div class="layui-input-block">
<input type="text" id="day" required lay-verify="required" placeholder="天数"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<a class="layui-btn" id="setCalendar">新增规则</a>
</div>
</div>
</form>
</div>
</div>
</body>
<script src="layui/layui.js"></script>
<script src="layui/jquery-3.2.1.js"></script>
<script>
layui.use('laydate', function () {
let dayDateObj
let marks = {}
let laydate = layui.laydate;
function showLayDate() {
laydate.render({
elem: '#calendar' //指定元素
, position: 'static'
, mark: marks
, done: function (value, date, endDate) {
console.log(date)
dayDateObj=date;
$('#dateText')[0].innerHTML = "从" + date.date + "号开始计算"
}
});
}
$.get("/calendar/all.do", function (json) {
//执行一个laydate实例
marks = json.data.date;
showLayDate()
})
$('#setCalendar').click(function () {
let interval=$('#interval')[0].value
let day=$('#day')[0].value
let intervalText=$('#interval').find("option:selected").text();
intervalText=intervalText.replace('X',day)
layer.open({
title: '确认'
,content: '确认从'+dayDateObj.date+'号开始, '+intervalText+' 开始提醒?'
,yes:function (index, layero) {
}
});
})
});
</script>
<style>
.myDiy {
width: 40%;
height: 300px;
margin-top: 10px;
margin-left: 25%;
}
.button {
width: 100px;
height: 100px;
font-size: 1em;
}
</style>
</html>