Update 4 files

- /llama.html
- /_posts/2024-01-20-renpy.md
- /index.html
- /proxylist.md
This commit is contained in:
mayx 2024-01-20 11:01:55 +00:00
parent d74fe7b4b8
commit 74cb7d028c
4 changed files with 25 additions and 389 deletions

View File

@ -0,0 +1,25 @@
---
layout: post
title: 如何在macOS上玩基于Ren'Py的视觉小说
tags: [Apple, macOS, 视觉小说]
---
跨平台的游戏移植起来就是简单啊<!--more-->
# 起因
最近我在玩[Winged Cloud](https://store.steampowered.com/developer/WingedCloud/)出的视觉小说他们家出的视觉小说画风都很不错比很多其他同行画的好看另外长度一般都很短大概1-2个小时就能看完很适合下班之后闲了看一部不过我现在已经换了MacBook要怎么玩呢他们家的视觉小说基本上都是用的Ren'Py引擎开发的。Ren'Py引擎的游戏本身其实原生就是跨平台的但是也许是因为我是直接从互联网上下载的macOS会有些验证之类的直接运行.app结尾的文件是没办法打开游戏的双击会显示应用程序无法打开……那该怎么运行呢
# 玩法研究
## 使用iOS版的RenPyViewer
不过看看之前[我在MacOS上玩游戏的经验](/2023/10/21/game.html)对于Apple芯片的Mac来说可以下载[RenPyViewer](https://apps.apple.com/us/app/renpyviewer/id1547796767)来玩。只是经过我的测试发现RenPyViewer能玩的游戏很有限因为它内置的Ren'Py引擎版本是7.5.3的如果游戏用的Ren'Py引擎和这个版本相差不大或者没有用到新版的特性之类的倒是能正常运行我试了一下Sakura MMO系列、Sakura Gamer系列等都能正常运行但只要运行游戏Ren'Py的版本过高或者过低的游戏都会报错尤其像新出的基本上都是8.0以上的版本了Python的版本也从2换成3了显然用RenPyViewer肯定是没法运行的。
## 使用Intel macOS版的RenPyViewer
其实在我发现iOS版的RenpyViewer不能运行一部分Ren'Py游戏之后我又去搜了一下在知乎上找到了iOS版的RenPyViewer作者发的文章介绍了[macOS如何游玩Ren'Py引擎游戏](https://zhuanlan.zhihu.com/p/477696534)其中包含了他为macOS做的RenPyViewer不过我下载看了一下是Intel版的……不过也许这个里面用的引擎更新一点一部分iOS版不能玩的这个版本就可以玩。
## 使用终端运行
但毕竟前面两个方法内置的引擎版本是固定的能玩的游戏也很少看来得想个通用的办法毕竟Ren'Py游戏在发行的时候是支持macOS的啊。所以玩又看了看Ren'Py开发的游戏发行之后一般在游戏文件夹里有一个.sh的文件看起来应该是给Linux系统运行使用的但是macOS也可以运行.sh的文件啊所以我就直接在终端运行了它结果macOS和Linux不一样的地方是所有从网上下载的可执行文件都必须签名不然就会报移到废纸篓之类的错关于这个问题我看网上说的好像是执行`xattr -r -d com.apple.quarantine <path>`就可以,不过后来我也忘了是出什么问题,最后是手动一个一个给每个可执行文件加的权限,最终倒是也运行起来了。
## 手动修改.app文件
不过每次运行要是用终端那不是很麻烦嘛,另外既然游戏里面明明有.app的文件为什么会运行不了呢后来我看了看发现Contents/MacOS文件夹下的文件并没有可执行权限我猜可能是和这个有关系加了可执行权限之后倒是没有报应用程序无法打开的错了但是还是不能运行点开之后在Dock栏跳了几下就消失了……然后我就去看了下那个可执行文件发现就是一个Shell脚本后面的版本换成可执行文件了里面定义了几个ROOT变量一个是和脚本同级的目录一个是和.app同级的目录还有一个是Contents/Resources/autorun目录这么看来正常情况下因为游戏是跨平台的游戏肯定不会在.app里面在外面的话……看现在macOS权限管的这么严格让它读取.app外面的文件估计不太行肯定只能读取.app里面的文件至于Intel macOS版的RenPyViewer我看了一下好像原理差不多是把游戏目录用软链接映射过去的所以才能在不直接获取.app外面的文件下运行。之后我又参考了一下其他直接在macOS发行的Ren'Py游戏感觉也差不多。所以解决方法也很简单要么把游戏文件放到Contents/Resources/autorun目录下要么做个软链接放过去我觉得单个.app管理起来会方便一些所以就直接把游戏文件全部移动进去了。试了一下总算可以正常运行了。而且多试了几个基本上都没有问题。
但有些Ren'Py游戏连.app都没提供我不知道SDK默认生成分发版的时候会不会包含macOS上用的.app文件不过也有可能是发行的时候只针对Windows所以删掉了对于一些非官方汉化版很有可能是汉化的人给删掉了。对于这种情况可以先搞清楚这个游戏使用的Ren'Py版本然后去Ren'Py官网下载对应版本的SDK把SDK中的renpy.app复制出来然后按照上面的方法把游戏拷进去就可以正常运行了。
另外macOS上还有一些坑比如说Windows的文件名是不区分大小写的但是macOS是区分的有时候他们写脚本的时候文件名和程序里可能有些比如CG之类的大小写不一致结果图片不能正常加载这种情况就只能用unrpa解包然后把对应的图片名改成正确的才能运行了当然Ren'Py提供了忽略错误的功能但是不知道为什么只有英文模式下有中文下就没有……这种情况还得先切换到英文才行。
# 总结
总的来看以后如果想在macOS上玩Ren'Py游戏优先应该用游戏自带的.app最好把Contents/MacOS下的文件添加可执行权限然后把文件全部移动到Contents/Resources/autorun下。不过旧版的Ren'Py基本上都是只有x86_64的可执行文件新的才有两种都支持的如果是用的Apple芯片的Mac最好先看看可执行文件是不是通用的如果不是优先应该先试试iOS版的RenPyViewer毕竟原生运行肯定要更省电一些如果不能运行再用上面的办法。

View File

@ -58,8 +58,6 @@ title: 首页 - 我的文章
<a href="{% unless site.github %}https://mabbs.github.io{% endunless %}/pixiv-index/">Pixiv图片索引API</a><br>
<a href="/llama.html">Cloudflare LLaMA 2</a><br>
<a href="/message.html">留言板</a><br>
<a href="/links.html">Links</a><br>

View File

@ -1,385 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Cloudflare AI</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon"
href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Ctext%20x='0'%20y='14'%20style='filter:%20invert(100%);'%3E☁%3C/text%3E%3C/svg%3E"
type="image/svg+xml" />
<style>
body {
font-family: 'Raleway', sans-serif;
margin: 0;
padding: 20px;
background-color: #222;
color: #fff;
backdrop-filter: blur(10px);
overflow: hidden;
height: 100vh;
}
h1 {
text-align: center;
font-weight: 900;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
font-size: 64px;
}
h2 {
text-align: center;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
font-size: 20px;
}
form {
margin-bottom: 20px;
display: flex;
justify-content: center;
/* Center items horizontally */
align-items: center;
/* Center items vertically */
position: fixed;
bottom: 12px;
width: 100vw;
border-radius: 10px;
padding: 10px;
/* Add some padding to give space around the items */
}
label {
font-weight: bold;
color: #ccc;
}
input[type="text"] {
width: 50%;
padding: 10px;
background-color: rgba(0, 0, 0, 0.3);
color: #fff;
border: none;
border-radius: 5px;
}
textarea {
width: 50%;
padding: 9px;
color: whitesmoke;
border: none;
border-radius: 5px;
font-size: 18px;
background-color: #222222;
}
textarea::-webkit-scrollbar {
display: none;
}
textarea:focus {
outline: none;
}
#response {
max-width: 80%;
height: calc(100% - 250px);
margin-left: 10%;
overflow-y: scroll;
}
#response::-webkit-scrollbar {
width: 10px;
border-radius: 50%;
}
.user-message {
background-color: rgba(71, 71, 71, 0.3);
padding: 10px;
margin-bottom: 10px;
margin-left: 40%;
max-width: 60%;
border-radius: 10px;
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.18);
color: whitesmoke;
}
.ai-message {
background-color: rgba(71, 71, 71, 0.3);
padding: 10px;
margin-bottom: 10px;
margin-right: 40%;
max-width: 60%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
color: whitesmoke;
}
p {
margin: 0;
padding: 0;
}
.smaller {
font-size: 15;
}
.fa-github {
text-decoration: none;
color: inherit;
position: fixed;
bottom: 0;
right: 0;
padding: 15px;
}
.dropbtn {
background-color: #191b1c;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
position: absolute;
top: 5px;
left: 5px;
padding: 10px;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #191b1c;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
color: #fff;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: black
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #444;
}
button {
font-size: 18px;
color: #e1e1e1;
font-family: inherit;
font-weight: 800;
cursor: pointer;
position: relative;
border: none;
background: none;
text-transform: uppercase;
transition-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1);
transition-duration: 400ms;
transition-property: color;
}
button:focus,
button:hover {
color: #fff;
}
button:focus:after,
button:hover:after {
width: 100%;
left: 0%;
}
button:after {
content: "";
pointer-events: none;
bottom: -2px;
left: 50%;
position: absolute;
width: 0%;
height: 2px;
background-color: #fff;
transition-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1);
transition-duration: 400ms;
transition-property: width, left;
}
.github-icon {
position: fixed;
right: 50px;
bottom: 50px;
}
/* if screen width<1000 then max -width=100% */
@media screen and (max-width: 1000px) {
#response {
max-width: 100%;
margin-left: 0;
height: calc(100% - 280px);
}
textarea {
width: 80%;
}
.github-icon {
visibility: hidden;
}
form {
bottom: 0;
}
.ai-message {
max-width: 80%;
min-width: 80%;
}
}
</style>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<h1>Cloudflare AI</h1>
<div class="dropdown">
<button class="dropbtn">Settings</button>
<div class="dropdown-content">
<a href="#" onclick='setApiUrl()'>Custom API URL</a>
<a href="#" onclick='setIDsession()'>Custom ID Session</a>
</div>
</div>
<div id="response">
<div class="ai-message">Hey there, how can i assist you?</div>
</div>
<form id="chatForm">
<textarea id="input" type="text" placeholder="Send a message"></textarea>
<button type="submit"></button>
</form>
<a class="fa fa-github github-icon" href="https://github.com/localuser-isback/Cloudflare-AI" style="font-size:36px">
<script>
// --------------- CONFIG --------------- //
// modify URL to your API
let apiUrl = "https://llama.mayx.eu.org"
// ----------- END OF CONFIG ------------ //
let uuid = '';
function setApiUrl() {
const customUrl = prompt("Enter custom API URL: ");
if (customUrl) {
apiUrl = customUrl;
}
}
function setIDsession() {
const customUUID = prompt("Enter custom session ID: ");
if (customUUID) {
uuid = customUUID;
}
}
function generateUUID() {
let newUUID = '';
const chars = 'abcdef0123456789';
for (let i = 0; i < 32; i++) {
const charIndex = Math.floor(Math.random() * chars.length);
newUUID += chars[charIndex];
if (i === 7 || i === 11 || i === 15 || i === 19) {
newUUID += '-';
}
}
return newUUID;
}
const chatForm = document.getElementById('chatForm');
const inputField = document.getElementById('input');
const responseDiv = document.getElementById('response');
function chat() {
var input = inputField.value;
input = encodeURIComponent(input)
const userMessageDiv = document.createElement('div');
userMessageDiv.className = 'user-message';
userMessageDiv.innerText = decodeURIComponent(input);
responseDiv.appendChild(userMessageDiv);
const loadingDiv = document.createElement('div');
loadingDiv.className = 'loading';
loadingDiv.innerHTML = `<svg width="30" height="30" viewBox="0 0 50 50"><circle cx="25" cy="25" r="20" stroke="black" stroke-width="4" fill="none" /><circle cx="25" cy="25" r="20" stroke="#3498db" stroke-width="4" fill="none" stroke-dasharray="90" stroke-dashoffset="0"><animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s" repeatCount="indefinite"/></circle></svg><center class="smaller">If you recive an error than wait 1-2 minutes refresh and try again.</center>`;
responseDiv.appendChild(loadingDiv);
axios.get(`${apiUrl}/${uuid}?q=${encodeURIComponent(input)}`)
.then((response) => {
responseDiv.removeChild(loadingDiv);
const aiMessages = response.data[0].response.filter(message => message.role === 'system' && message.content.response);
if (aiMessages.length > 0) {
const lastAiMessage = aiMessages[aiMessages.length - 1];
const aiMessageDiv = document.createElement('div');
aiMessageDiv.className = 'ai-message';
aiMessageDiv.innerHTML = marked.parse(lastAiMessage.content.response);
responseDiv.appendChild(aiMessageDiv);
}
inputField.value = '';
})
.catch((error) => {
console.log("Error receiving response:", error);
});
}
chatForm.addEventListener('submit', (event) => {
event.preventDefault();
chat()
});
inputField.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
if (!event.shiftKey) {
event.preventDefault();
chat()
}
}
});
if (!uuid) {
uuid = generateUUID();
}
</script>
</body>
</html>

View File

@ -35,5 +35,3 @@ title: 代理列表
- <https://unmayx.medium.com/>
- <https://mayx.cnblogs.com/>
- <https://mayx.xlog.app/>
- <https://mayx.proselog.com/>
- <https://mayx.substack.com/>