qiuqiu vor 6 Monaten
Ursprung
Commit
3c65c4af75

+ 0 - 6
.idea/workspace.xml

@@ -7,13 +7,7 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" id="fec10672-acda-4616-894b-a4b6f93aea6f" name="Default Changelist" comment="">
-      <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/笔记文件/2.笔记/Playworks 临时记录.md" beforeDir="false" afterPath="$PROJECT_DIR$/笔记文件/2.笔记/Playworks 临时记录.md" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/笔记文件/2.笔记/Spine动画参考.md" beforeDir="false" afterPath="$PROJECT_DIR$/笔记文件/2.笔记/Spine动画参考.md" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/笔记文件/2.笔记/广告试玩 临时记录.md" beforeDir="false" afterPath="$PROJECT_DIR$/笔记文件/2.笔记/广告试玩 临时记录.md" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/笔记文件/2.笔记/灵感_其他_第一章.md" beforeDir="false" afterPath="$PROJECT_DIR$/笔记文件/2.笔记/灵感_其他_第一章.md" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/笔记文件/日记/2025_06_18_星期三.md" beforeDir="false" afterPath="$PROJECT_DIR$/笔记文件/日记/2025_06_18_星期三.md" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/笔记文件/看板/看板.md" beforeDir="false" afterPath="$PROJECT_DIR$/笔记文件/看板/看板.md" afterDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />

+ 144 - 0
笔记文件/2.笔记/图片等比压缩.md

@@ -0,0 +1,144 @@
+#python 
+#前端 
+
+很多时候,网页和实际游戏不一样,是不需要使用到,太大尺寸,或者太大分辨率的,但是表现要基本一致,所以可以考虑,使用等比压缩图片;
+在执行python脚本逻辑之前,需要确保一下,以下python库,是正常的,一个是路径,另一个是`Pillow`图像库
+
+``` shell
+ pip install pathlib
+ pip install Pillow
+```
+
+然后,是等比压缩的python脚本,逻辑实现:
+## resize.py
+
+``` py
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import os
+from PIL import Image
+from pathlib import Path
+
+def resize_image(
+    input_path: str,
+    output_path: str = None,
+    max_size: tuple = None,
+    scale: float = None,
+    quality: int = 85,
+    keep_exif: bool = True
+) -> None:
+    """
+    等比缩小图片
+    
+    :param input_path: 输入图片路径
+    :param output_path: 输出路径(默认添加后缀 _resized)
+    :param max_size: 最大尺寸 (width, height),优先级高于 scale
+    :param scale: 缩放比例(0-1之间)
+    :param quality: 输出质量(1-100)
+    :param keep_exif: 是否保留EXIF信息
+    """
+    if not os.path.exists(input_path):
+        raise FileNotFoundError(f"输入文件不存在: {input_path}")
+    
+    if max_size is None and scale is None:
+        raise ValueError("必须指定 max_size 或 scale 参数")
+    
+    # 设置默认输出路径
+    if output_path is None:
+        p = Path(input_path)
+        output_path = str(p.parent / f"{p.stem}_resized{p.suffix}")
+    
+    with Image.open(input_path) as img:
+        # 保留EXIF信息
+        exif = img.info.get('exif') if keep_exif else None
+        
+        # 计算新尺寸
+        width, height = img.size
+        if max_size:
+            new_width, new_height = max_size
+            ratio = min(new_width/width, new_height/height)
+        else:
+            ratio = scale
+        
+        new_size = (int(width * ratio), int(height * ratio))
+        
+        # 使用LANCZOS算法保持高质量缩小
+        img_resized = img.resize(new_size, Image.LANCZOS)
+        
+        # 保存图片(根据格式调整参数)
+        save_kwargs = {'quality': quality}
+        if input_path.lower().endswith('.png'):
+            save_kwargs['compress_level'] = 6
+        if exif:
+            save_kwargs['exif'] = exif
+            
+        img_resized.save(output_path, **save_kwargs)
+        print(f"图片已保存至: {output_path} (原始尺寸: {img.size} -> 新尺寸: {new_size})")
+
+def batch_resize(
+    input_dir: str,
+    output_dir: str = None,
+    **kwargs
+) -> None:
+    """
+    批量处理目录中的所有图片
+    """
+    if not os.path.isdir(input_dir):
+        raise NotADirectoryError(f"输入目录不存在: {input_dir}")
+    
+    if output_dir is None:
+        output_dir = os.path.join(input_dir, "resized")
+    os.makedirs(output_dir, exist_ok=True)
+    
+    supported_formats = ('.jpg', '.jpeg', '.png', '.webp')
+    for filename in os.listdir(input_dir):
+        if filename.lower().endswith(supported_formats):
+            input_path = os.path.join(input_dir, filename)
+            output_path = os.path.join(output_dir, filename)
+            try:
+                resize_image(input_path, output_path, **kwargs)
+            except Exception as e:
+                print(f"处理失败 {filename}: {str(e)}")
+
+if __name__ == "__main__":
+    import argparse
+    
+    parser = argparse.ArgumentParser(description="图片等比缩小工具")
+    parser.add_argument("input", help="输入文件或目录路径")
+    parser.add_argument("--output", help="输出路径(文件或目录)")
+    parser.add_argument("--max_size", nargs=2, type=int, 
+                       help="最大宽高(如 800 600)")
+    parser.add_argument("--scale", type=float, 
+                       help="缩放比例(如 0.5 表示缩小一半)")
+    parser.add_argument("--quality", type=int, default=85,
+                       help="输出质量(1-100,默认85)")
+    parser.add_argument("--no_exif", action="store_true",
+                       help="不保留EXIF信息")
+    
+    args = parser.parse_args()
+    
+    kwargs = {
+        'max_size': tuple(args.max_size) if args.max_size else None,
+        'scale': args.scale,
+        'quality': args.quality,
+        'keep_exif': not args.no_exif
+    }
+    
+    if os.path.isfile(args.input):
+        resize_image(args.input, args.output, **kwargs)
+    elif os.path.isdir(args.input):
+        batch_resize(args.input, args.output, **kwargs)
+    else:
+        print("错误:输入路径必须是文件或目录")
+```
+
+## 调用方式
+同一文件夹,示例:
+等比缩放0.6倍
+
+``` shell
+python .\resize.py .\ImageReSize\ --output .\ImageReSize_2\ --scale 0.6
+```
+
+![[Pasted image 20250620103001.png]]

+ 56 - 1
笔记文件/2.笔记/广告试玩 临时记录.md

@@ -24,4 +24,59 @@ AppLovin上传和测试链接:https://p.applov.in/playablePreview?create=1&qr=
 
 ![[Pasted image 20250616165255.png]]
 
-![[img_v3_02n7_7d05e50a-a8e0-436a-b9f4-d3dbab43d5hu.jpg]]
+![[img_v3_02n7_7d05e50a-a8e0-436a-b9f4-d3dbab43d5hu.jpg]]
+
+在playwork生成的,单html文件中,预加载的时候,会有这个进度条
+
+![[Pasted image 20250620095345.png]]
+
+是因为有这仨css样式
+
+``` css
+.preloader__outer__bar {
+    display: flex;
+    justify-content: left;
+    align-items: center;
+    width: 100%;
+    height: 1.2vmax;
+    margin: 0.4vmax;
+    border-radius: 1000px;
+}
+
+.preloader__outer__bar:before {
+    content: '';
+    position: absolute;
+    border: 0.3vmax solid #fff;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    border-radius: 100vh;
+}
+
+.preloader__bar {
+    width: 0;
+    height: calc(100% - 0.4vmax);
+    margin: 0.2vmax;
+    border-radius: 10000px;
+    box-sizing: border-box;
+    background: white;
+    animation: loading 8s forwards;
+}
+```
+
+解决方法:
+
+![[Pasted image 20250620095940.png]]
+
+作用说明:
+
+![[Pasted image 20250620100408.png]]
+
+![[Pasted image 20250620100450.png]]
+
+![[Pasted image 20250620100509.png]]
+
+重新打开网页,可以看到,是生效的了:
+
+![[Pasted image 20250620100604.png]]

+ 148 - 0
笔记文件/2.笔记/网页压缩.md

@@ -0,0 +1,148 @@
+#python 
+#前端
+
+通过unity转成html后,会有很多格式化相关字符&空格&换行,也会占据很多空间,可以通过以下脚本,对html进行压缩处理;
+在执行脚本之前,需要先确认,是安装了,以下库
+
+``` shell
+pip install bs4
+pip install BeautifulSoup
+```
+
+## html_minifier.py
+
+``` py
+# html_minifier.py
+import re
+import logging
+from bs4 import BeautifulSoup, Comment
+
+class HTMLMinifier:
+    """
+    HTML压缩工具类,提供静态方法用于HTML最小化处理
+    功能:
+    1. 移除所有HTML注释
+    2. 压缩空白字符(保留pre/code/textarea内容)
+    3. 可选移除冗余属性
+    """
+    
+    @staticmethod
+    def minify(html_content, remove_redundant_attrs=False):
+        """
+        最小化HTML内容
+        
+        参数:
+            html_content (str): 原始HTML内容
+            remove_redundant_attrs (bool): 是否移除冗余属性(如type="text/javascript")
+            
+        返回:
+            str: 压缩后的HTML内容
+        异常:
+            ValueError: 当输入不是字符串时
+        """
+        if not isinstance(html_content, str):
+            raise ValueError("输入必须是字符串类型")
+            
+        try:
+            soup = BeautifulSoup(html_content, 'html.parser')
+            
+            # 移除注释
+            for comment in soup.find_all(string=lambda text: isinstance(text, Comment)):
+                comment.extract()
+            
+            # 压缩空白
+            for element in soup.find_all(string=True):
+                if element.parent.name not in ['pre', 'code', 'textarea']:
+                    element.replace_with(re.sub(r'\s+', ' ', element.string.strip()))
+            
+            # 可选:移除冗余属性
+            if remove_redundant_attrs:
+                for tag in soup.find_all(True):
+                    if tag.name == 'script' and tag.get('type') == 'text/javascript':
+                        del tag['type']
+                    if tag.name == 'style' and tag.get('type') == 'text/css':
+                        del tag['type']
+                    if tag.name == 'link' and tag.get('type') == 'text/css':
+                        del tag['type']
+            
+            return str(soup)
+        except Exception as e:
+            logging.error(f"HTML压缩失败: {str(e)}")
+            raise
+
+def process_file(input_path, output_path=None, **kwargs):
+    """
+    文件处理入口函数
+    
+    参数:
+        input_path (str): 输入文件路径
+        output_path (str): 输出文件路径(默认添加.min后缀)
+        **kwargs: 传递给minify的参数
+        
+    返回:
+        tuple: (压缩后内容, 压缩率)
+    """
+    try:
+        # 读取输入文件
+        with open(input_path, 'r', encoding='utf-8') as f:
+            original = f.read()
+        
+        # 处理输出路径
+        if not output_path:
+            if input_path.endswith('.html'):
+                output_path = input_path.replace('.html', '.min.html')
+            else:
+                output_path = input_path + '.min'
+        
+        # 执行压缩
+        minified = HTMLMinifier.minify(original, **kwargs)
+        
+        # 写入输出文件
+        with open(output_path, 'w', encoding='utf-8') as f:
+            f.write(minified)
+        
+        # 计算压缩率
+        orig_size = len(original.encode('utf-8'))
+        min_size = len(minified.encode('utf-8'))
+        ratio = (orig_size - min_size) / orig_size * 100
+        
+        logging.info(f"压缩完成: {orig_size} → {min_size} 字节 (缩减 {ratio:.1f}%)")
+        return minified, ratio
+        
+    except Exception as e:
+        logging.error(f"文件处理失败: {str(e)}")
+        raise
+
+if __name__ == '__main__':
+    import argparse
+    
+    # 配置日志
+    logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
+    
+    # 设置命令行参数
+    parser = argparse.ArgumentParser(description='HTML文件压缩工具')
+    parser.add_argument('input', help='输入HTML文件路径')
+    parser.add_argument('-o', '--output', help='输出文件路径')
+    parser.add_argument('-r', '--remove-attrs', action='store_true', help='移除冗余属性')
+    args = parser.parse_args()
+    
+    # 执行压缩
+    try:
+        process_file(
+            args.input,
+            output_path=args.output,
+            remove_redundant_attrs=args.remove_attrs
+        )
+    except Exception as e:
+        logging.error(f"处理失败: {e}")
+        exit(1)
+```
+
+## 调用方式:
+示例,同级目录:
+
+``` shell
+python .\html_minifier.py .\NewTest_2.html
+```
+
+![[Pasted image 20250620101456.png]]

+ 248 - 0
笔记文件/2.笔记/谷歌access token授权码认证.md

@@ -0,0 +1,248 @@
+#python 
+#unity/日常积累 
+
+谷歌game service v2 版本,会返回授权码:
+auth_code (str): Google授权码(以4/开头的字符串)
+
+在执行相关逻辑之前,确保安装了,python库中,谷歌认证相关:
+
+``` shell
+ pip install google-auth requests
+```
+
+另外,还需要准备的材料:
+
+![[Pasted image 20250620103522.png]]
+
+## google_token.py
+
+``` py
+import requests
+import json
+import sys
+from google.oauth2 import id_token
+from google.auth.transport import requests as google_requests
+
+def exchange_auth_code(auth_code, client_id, client_secret):
+    """
+    用授权码交换获取访问令牌和ID令牌
+    
+    参数:
+        auth_code (str): Google授权码(以4/开头的字符串)
+        client_id (str): 你的Google OAuth客户端ID
+        client_secret (str): 你的Google OAuth客户端密钥
+        
+    返回:
+        dict: 包含tokens和用户信息的字典
+    """
+    token_url = "https://oauth2.googleapis.com/token"
+    payload = {
+        "code": auth_code,
+        "client_id": client_id,
+        "client_secret": client_secret,
+        "redirect_uri": "http://localhost",
+        "grant_type": "authorization_code"
+    }
+    
+    print(f"正在交换授权码...")
+    try:
+        response = requests.post(token_url, data=payload)
+        
+        if response.status_code == 200:
+            token_data = response.json()
+            print(f"令牌交换成功!")
+            
+            # 获取各种令牌
+            access_token = token_data.get("access_token")
+            id_token_str = token_data.get("id_token")
+            refresh_token = token_data.get("refresh_token")
+            
+            # 安全地打印令牌信息,避免NoneType错误
+            if access_token:
+                print(f"\n访问令牌(Access Token): {access_token[:20]}...(已截断)")
+            else:
+                print("\n访问令牌(Access Token): None")
+                
+            if id_token_str:
+                print(f"ID令牌(ID Token): {id_token_str[:20]}...(已截断)")
+            else:
+                print("ID令牌(ID Token): None")
+                
+            if refresh_token:
+                print(f"刷新令牌(Refresh Token): {refresh_token[:20]}...(已截断)")
+            else:
+                print("刷新令牌(Refresh Token): None")
+            
+            # 保存完整令牌到文件以备后用
+            try:
+                with open("tokens.json", "w") as f:
+                    json.dump(token_data, f, indent=2)
+                    print(f"\n已将完整令牌保存到 tokens.json 文件")
+            except Exception as e:
+                print(f"保存令牌到文件失败: {e}")
+            
+            # 验证ID令牌并获取用户信息
+            if id_token_str:
+                try:
+                    user_info = verify_id_token(id_token_str, client_id)
+                    return {
+                        "tokens": token_data,
+                        "user_info": user_info
+                    }
+                except Exception as e:
+                    print(f"ID令牌验证失败: {e}")
+                    return {
+                        "tokens": token_data,
+                        "user_info": None
+                    }
+            else:
+                print("响应中没有ID令牌")
+                return {
+                    "tokens": token_data,
+                    "user_info": None
+                }
+        else:
+            print(f"错误: {response.status_code}")
+            print(response.text)
+            return None
+    except Exception as e:
+        print(f"请求过程中发生错误: {e}")
+        return None
+
+def verify_id_token(id_token_str, client_id):
+    """
+    验证ID令牌并返回用户信息
+    
+    参数:
+        id_token_str (str): 要验证的ID令牌
+        client_id (str): 你的Google OAuth客户端ID
+        
+    返回:
+        dict: 用户信息字典
+    """
+    print(f"\n正在验证ID令牌...")
+    try:
+        idinfo = id_token.verify_oauth2_token(
+            id_token_str, 
+            google_requests.Request(), 
+            client_id
+        )
+        
+        # 验证发行者
+        if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
+            raise ValueError('错误的令牌发行者.')
+        
+        print(f"ID令牌验证成功!")
+        return idinfo
+    except Exception as e:
+        print(f"ID令牌验证失败: {e}")
+        raise
+
+def get_user_info_from_token(access_token):
+    """
+    使用访问令牌获取用户信息
+    
+    参数:
+        access_token (str): 访问令牌
+        
+    返回:
+        dict: 用户信息字典
+    """
+    if not access_token:
+        print("访问令牌为空,无法获取用户信息")
+        return None
+        
+    print(f"\n使用访问令牌获取用户信息...")
+    
+    userinfo_url = "https://openidconnect.googleapis.com/v1/userinfo"
+    headers = {
+        "Authorization": f"Bearer {access_token}"
+    }
+    
+    try:
+        response = requests.get(userinfo_url, headers=headers)
+        
+        if response.status_code == 200:
+            user_info = response.json()
+            print(f"获取用户信息成功!")
+            return user_info
+        else:
+            print(f"获取用户信息失败: {response.status_code}")
+            print(response.text)
+            return None
+    except Exception as e:
+        print(f"获取用户信息过程中发生错误: {e}")
+        return None
+
+def main():
+    """主函数,处理命令行参数并执行令牌交换"""
+    try:
+        if len(sys.argv) < 4:
+            print("用法: python exchange_code.py <授权码> <客户端ID> <客户端密钥>")
+            sys.exit(1)
+        
+        auth_code = sys.argv[1]
+        client_id = sys.argv[2]
+        client_secret = sys.argv[3]
+        
+        # 安全地截断显示参数
+        auth_code_display = auth_code[:10] + "...(已截断)" if len(auth_code) > 10 else auth_code
+        client_id_display = client_id[:15] + "...(已截断)" if len(client_id) > 15 else client_id
+        client_secret_display = client_secret[:5] + "...(已截断)" if len(client_secret) > 5 else client_secret
+        
+        print("-" * 50)
+        print("Google授权码交换工具")
+        print("-" * 50)
+        print(f"授权码: {auth_code_display}")
+        print(f"客户端ID: {client_id_display}")
+        print(f"客户端密钥: {client_secret_display}")
+        print("-" * 50)
+        
+        result = exchange_auth_code(auth_code, client_id, client_secret)
+        
+        if result:
+            tokens = result.get("tokens", {})
+            user_info = result.get("user_info")
+            
+            # 如果ID令牌验证失败,尝试使用访问令牌获取用户信息
+            if not user_info and tokens.get("access_token"):
+                user_info = get_user_info_from_token(tokens["access_token"])
+            
+            if user_info:
+                print("\n----- 用户信息 -----")
+                print(f"用户ID: {user_info.get('sub') or user_info.get('id', 'N/A')}")
+                print(f"电子邮件: {user_info.get('email', 'N/A')}")
+                print(f"姓名: {user_info.get('name', 'N/A')}")
+                print(f"头像: {user_info.get('picture', 'N/A')}")
+                
+                # 保存用户信息到文件
+                try:
+                    with open("user_info.json", "w") as f:
+                        json.dump(user_info, f, indent=2)
+                        print(f"\n已将用户信息保存到 user_info.json 文件")
+                except Exception as e:
+                    print(f"保存用户信息到文件失败: {e}")
+            else:
+                print("\n无法获取用户信息")
+        else:
+            print("\n令牌交换失败")
+            sys.exit(1)
+        
+        print("\n处理完成!")
+    except Exception as e:
+        print(f"程序执行过程中发生错误: {e}")
+        sys.exit(1)
+
+if __name__ == "__main__":
+    main() 
+```
+
+调用方式
+
+``` shell
+python .\google_token.py 4/0AUJR-x5Sbmm9wToj9ai84DdPRf-FaubSQieqnV0k2OWkVeqGg_XW08bGgyMDIxoTilbH3A 956550854222-pfjuen977e59l6hif1tj08bibh93tguu.apps.googleusercontent.com AIzaSyDLJnWUHh6o-F4e9N0fUsbGeS2sIoqyLr4
+```
+
+传参分别是:授权码、web客户端ID、web客户端密钥
+
+![[Pasted image 20250620103712.png]]

+ 0 - 1
笔记文件/日记/2025_06_13_星期五.md

@@ -22,7 +22,6 @@
 # 今日任务
 
 - [x] 今晚记得拿快递
-- [ ] 中午确认一下 淘宝泳衣
 - [x] 今晚前记得美团买花
 - [ ] 把slot的后缀评论逻辑,也迁移到中台库
 - [x] 也买一下健身房 洗发水+沐浴露

+ 1 - 1
笔记文件/日记/2025_06_18_星期三.md

@@ -22,7 +22,7 @@
 # 今日任务
 
 - [x] 找一套简单的slot源码去改逻辑
-- [ ] 用一下拿到的美术资源去替换slot源码的
+- [x] 用一下拿到的美术资源去替换slot源码的
 - [ ] 把最后一个换皮广告处理了
 - [x] 跟进新加坡 更换IP进度
 - [ ] 把谷歌登录sdk 添加到元素安卓包,完善逻辑

+ 34 - 0
笔记文件/日记/2025_06_20_星期五.md

@@ -0,0 +1,34 @@
+
+09:51
+
+###### [[unity日常积累]]
+
+###### [[节奏天国]]
+
+###### [[帧同步王者荣耀]]
+
+###### [[从零开发跨平台通用日志插件]]
+
+###### [[通用异步网络通信库]]
+
+###### [[高性能定时系统实现]]
+
+###### [[学习资料]]
+
+###### [[其他]]
+
+#### [[看板]]
+
+# 今日任务
+
+- [ ] 记得买一下泳衣
+- [ ] 记得买花
+- [ ] 记得买一下酸奶
+- [ ] 尝试修复一下 x项目的报错相关
+- [ ] 测试dotween在广告试玩中的作用效果
+---
+[[网页压缩]]
+[[图片等比压缩]]
+[[谷歌access token授权码认证]]
+
+# Journal

BIN
笔记文件/附件/Pasted image 20250620095345.png


BIN
笔记文件/附件/Pasted image 20250620095940.png


BIN
笔记文件/附件/Pasted image 20250620100408.png


BIN
笔记文件/附件/Pasted image 20250620100450.png


BIN
笔记文件/附件/Pasted image 20250620100509.png


BIN
笔记文件/附件/Pasted image 20250620100604.png


BIN
笔记文件/附件/Pasted image 20250620101456.png


BIN
笔记文件/附件/Pasted image 20250620103001.png


BIN
笔记文件/附件/Pasted image 20250620103522.png


BIN
笔记文件/附件/Pasted image 20250620103712.png